Auto merge of #139588 - Kobzol:rust-analyzer-opt, r=jieyouxu
Use LTO to optimize Rust tools (cargo, miri, rustfmt, clippy, Rust Analyzer)
Trying if LTO/PGO can help RA's performance, and by how much. As `@Noratrieb` suggested, we could actually LTO optimize all the important tools.
CC `@Veykril` I realized that we don't even do LTO for Rust Analyzer, that could be a very low hanging fruit to improve its performance :sweat_smile:
try-job: dist-x86_64-linux
diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md
index 3a9d840..aedc15a 100644
--- a/.github/ISSUE_TEMPLATE/tracking_issue.md
+++ b/.github/ISSUE_TEMPLATE/tracking_issue.md
@@ -41,7 +41,10 @@
- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring
instructions?)
- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
-- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure])
+- [ ] Style updates for any new syntax ([nightly-style-procedure])
+ - [ ] Style team decision on new formatting
+ - [ ] Formatting for new syntax has been added to the [Style Guide]
+ - [ ] (non-blocking) Formatting has been implemented in `rustfmt`
- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])
[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
diff --git a/Cargo.lock b/Cargo.lock
index 2175f08..982ab7e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -379,7 +379,7 @@
name = "cargo-miri"
version = "0.1.0"
dependencies = [
- "cargo_metadata 0.18.1",
+ "cargo_metadata 0.19.2",
"directories",
"rustc-build-sysroot",
"rustc_tools_util 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1012,11 +1012,11 @@
[[package]]
name = "directories"
-version = "5.0.1"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
dependencies = [
- "dirs-sys",
+ "dirs-sys 0.5.0",
]
[[package]]
@@ -1025,7 +1025,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
- "dirs-sys",
+ "dirs-sys 0.4.1",
]
[[package]]
@@ -1046,18 +1046,30 @@
dependencies = [
"libc",
"option-ext",
- "redox_users",
+ "redox_users 0.4.6",
"windows-sys 0.48.0",
]
[[package]]
+name = "dirs-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users 0.5.0",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
- "redox_users",
+ "redox_users 0.4.6",
"winapi",
]
@@ -2213,20 +2225,6 @@
[[package]]
name = "measureme"
-version = "11.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfa4a40f09af7aa6faef38285402a78847d0d72bf8827006cd2a332e1e6e4a8d"
-dependencies = [
- "log",
- "memmap2",
- "parking_lot",
- "perf-event-open-sys",
- "rustc-hash 1.1.0",
- "smallvec",
-]
-
-[[package]]
-name = "measureme"
version = "12.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570a507d8948a66a97f42cbbaf8a6bb9516a51017d4ee949502ad7a10a864395"
@@ -2314,6 +2312,7 @@
version = "0.1.0"
dependencies = [
"aes",
+ "bitflags",
"chrono",
"chrono-tz",
"colored",
@@ -2322,7 +2321,7 @@
"libc",
"libffi",
"libloading",
- "measureme 11.0.1",
+ "measureme",
"rand 0.9.0",
"regex",
"rustc_version",
@@ -2330,7 +2329,7 @@
"tempfile",
"tikv-jemalloc-sys",
"ui_test",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3030,6 +3029,17 @@
]
[[package]]
+name = "redox_users"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
+dependencies = [
+ "getrandom 0.2.15",
+ "libredox",
+ "thiserror 2.0.12",
+]
+
+[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3208,17 +3218,6 @@
]
[[package]]
-name = "rustc-rayon"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cd9fb077db982d7ceb42a90471e5a69a990b58f71e06f0d8340bb2cf35eb751"
-dependencies = [
- "either",
- "indexmap",
- "rustc-rayon-core",
-]
-
-[[package]]
name = "rustc-rayon-core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3469,7 +3468,7 @@
"gimli 0.31.1",
"itertools",
"libc",
- "measureme 12.0.1",
+ "measureme",
"object 0.36.7",
"rustc-demangle",
"rustc_abi",
@@ -3584,12 +3583,12 @@
"indexmap",
"jobserver",
"libc",
- "measureme 12.0.1",
+ "measureme",
"memmap2",
"parking_lot",
"portable-atomic",
"rustc-hash 2.1.1",
- "rustc-rayon",
+ "rustc-rayon-core",
"rustc-stable-hash",
"rustc_arena",
"rustc_graphviz",
@@ -3935,7 +3934,6 @@
name = "rustc_interface"
version = "0.0.0"
dependencies = [
- "rustc-rayon",
"rustc-rayon-core",
"rustc_abi",
"rustc_ast",
@@ -4344,7 +4342,7 @@
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
- "measureme 12.0.1",
+ "measureme",
"rustc_data_structures",
"rustc_hashes",
"rustc_hir",
@@ -4446,6 +4444,7 @@
"bitflags",
"getopts",
"libc",
+ "rand 0.9.0",
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 843d5ca..59b74d2 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1829,7 +1829,7 @@ pub struct PointeeInfo {
pub safe: Option<PointerKind>,
/// If `safe` is `Some`, then the pointer is either null or dereferenceable for this many bytes.
/// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration
- /// of this function call", i.e. it is UB for the memory that this pointer points to to be freed
+ /// of this function call", i.e. it is UB for the memory that this pointer points to be freed
/// while this function is still running.
/// The size can be zero if the pointer is not dereferenceable.
pub size: Size,
diff --git a/compiler/rustc_ast/src/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs
index 04c8162..323a8fa 100644
--- a/compiler/rustc_ast/src/expand/mod.rs
+++ b/compiler/rustc_ast/src/expand/mod.rs
@@ -13,12 +13,12 @@
#[derive(Debug, Clone, Encodable, Decodable, HashStable_Generic)]
pub struct StrippedCfgItem<ModId = DefId> {
pub parent_module: ModId,
- pub name: Ident,
+ pub ident: Ident,
pub cfg: MetaItem,
}
impl<ModId> StrippedCfgItem<ModId> {
pub fn map_mod_id<New>(self, f: impl FnOnce(ModId) -> New) -> StrippedCfgItem<New> {
- StrippedCfgItem { parent_module: f(self.parent_module), name: self.name, cfg: self.cfg }
+ StrippedCfgItem { parent_module: f(self.parent_module), ident: self.ident, cfg: self.cfg }
}
}
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 9899ee0..2296b05 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -47,7 +47,7 @@
use rustc_hir::def_id::DefId;
use rustc_middle::span_bug;
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
-use rustc_span::{Ident, Span};
+use rustc_span::{Ident, Span, Symbol};
use {rustc_ast as ast, rustc_hir as hir};
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
@@ -234,12 +234,13 @@ fn lower_delegation_sig(
hir::FnSig { decl, header, span }
}
- fn generate_param(&mut self, span: Span) -> (hir::Param<'hir>, NodeId) {
+ fn generate_param(&mut self, idx: usize, span: Span) -> (hir::Param<'hir>, NodeId) {
let pat_node_id = self.next_node_id();
let pat_id = self.lower_node_id(pat_node_id);
+ let ident = Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}")));
let pat = self.arena.alloc(hir::Pat {
hir_id: pat_id,
- kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, Ident::empty(), None),
+ kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, ident, None),
span,
default_binding_modes: false,
});
@@ -247,9 +248,9 @@ fn generate_param(&mut self, span: Span) -> (hir::Param<'hir>, NodeId) {
(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
}
- fn generate_arg(&mut self, param_id: HirId, span: Span) -> hir::Expr<'hir> {
+ fn generate_arg(&mut self, idx: usize, param_id: HirId, span: Span) -> hir::Expr<'hir> {
let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
- ident: Ident::empty(),
+ ident: Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}"))),
hir_id: self.next_id(),
res: Res::Local(param_id),
args: None,
@@ -273,7 +274,7 @@ fn lower_delegation_body(
let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
for idx in 0..param_count {
- let (param, pat_node_id) = this.generate_param(span);
+ let (param, pat_node_id) = this.generate_param(idx, span);
parameters.push(param);
let arg = if let Some(block) = block
@@ -289,7 +290,7 @@ fn lower_delegation_body(
this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
this.lower_target_expr(&block)
} else {
- this.generate_arg(param.pat.hir_id, span)
+ this.generate_arg(idx, param.pat.hir_id, span)
};
args.push(arg);
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 958a691..59099e5 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -645,7 +645,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
- this.lower_fn_params_to_names(fdec),
+ this.lower_fn_params_to_idents(fdec),
)
});
@@ -833,7 +833,7 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
}) => {
// FIXME(contracts): Deny contract here since it won't apply to
// any impl method or callees.
- let names = self.lower_fn_params_to_names(&sig.decl);
+ let idents = self.lower_fn_params_to_idents(&sig.decl);
let (generics, sig) = self.lower_method_sig(
generics,
sig,
@@ -851,7 +851,7 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
(
*ident,
generics,
- hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)),
+ hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),
false,
)
}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 6aa6a18..22a293d 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1247,7 +1247,7 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
safety: self.lower_safety(f.safety, hir::Safety::Safe),
abi: self.lower_extern(f.ext),
decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
- param_names: self.lower_fn_params_to_names(&f.decl),
+ param_idents: self.lower_fn_params_to_idents(&f.decl),
}))
}
TyKind::UnsafeBinder(f) => {
@@ -1494,7 +1494,7 @@ fn lower_precise_capturing_args(
}))
}
- fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
+ fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
PatKind::Missing => None,
PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
@@ -2034,7 +2034,9 @@ fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
}
fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
- match c.value.kind {
+ // We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
+ // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
+ match c.value.peel_parens().kind {
ExprKind::Underscore => {
if !self.tcx.features().generic_arg_infer() {
feature_err(
diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs
index 4c42dd1..bc7f227 100644
--- a/compiler/rustc_ast_pretty/src/pprust/tests.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs
@@ -7,12 +7,12 @@
fn fun_to_string(
decl: &ast::FnDecl,
header: ast::FnHeader,
- name: Ident,
+ ident: Ident,
generics: &ast::Generics,
) -> String {
to_string(|s| {
s.head("");
- s.print_fn(decl, header, Some(name), generics);
+ s.print_fn(decl, header, Some(ident), generics);
s.end(); // Close the head box.
s.end(); // Close the outer box.
})
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 1f4eb0c..8a8ecc3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2500,11 +2500,11 @@ fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
);
let ty::Tuple(params) = tupled_params.kind() else { return };
- // Find the first argument with a matching type, get its name
- let Some(this_name) = params.iter().zip(tcx.hir_body_param_names(closure.body)).find_map(
- |(param_ty, name)| {
+ // Find the first argument with a matching type and get its identifier.
+ let Some(this_name) = params.iter().zip(tcx.hir_body_param_idents(closure.body)).find_map(
+ |(param_ty, ident)| {
// FIXME: also support deref for stuff like `Rc` arguments
- if param_ty.peel_refs() == local_ty { name } else { None }
+ if param_ty.peel_refs() == local_ty { ident } else { None }
},
) else {
return;
@@ -3774,7 +3774,7 @@ fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>
method_args,
*fn_span,
call_source.from_hir_call(),
- self.infcx.tcx.fn_arg_names(method_did)[0],
+ self.infcx.tcx.fn_arg_idents(method_did)[0],
)
{
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index eb664f1..f9f63ae 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1026,7 +1026,7 @@ pub(super) fn move_spans(
method_args,
*fn_span,
call_source.from_hir_call(),
- self.infcx.tcx.fn_arg_names(method_did)[0],
+ self.infcx.tcx.fn_arg_idents(method_did)[0],
);
return FnSelfUse {
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 351413d..4161829 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -234,7 +234,7 @@ pub(crate) fn expand(
let meta_item_vec: ThinVec<MetaItemInner> = match meta_item.kind {
ast::MetaItemKind::List(ref vec) => vec.clone(),
_ => {
- dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
+ dcx.emit_err(errors::AutoDiffMissingConfig { span: item.span() });
return vec![item];
}
};
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 8862965..a91f2d3 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -20,14 +20,14 @@
struct ProcMacroDerive {
id: NodeId,
trait_name: Symbol,
- function_name: Ident,
+ function_ident: Ident,
span: Span,
attrs: Vec<Symbol>,
}
struct ProcMacroDef {
id: NodeId,
- function_name: Ident,
+ function_ident: Ident,
span: Span,
}
@@ -95,7 +95,7 @@ fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
fn collect_custom_derive(
&mut self,
item: &'a ast::Item,
- function_name: Ident,
+ function_ident: Ident,
attr: &'a ast::Attribute,
) {
let Some((trait_name, proc_attrs)) =
@@ -109,7 +109,7 @@ fn collect_custom_derive(
id: item.id,
span: item.span,
trait_name,
- function_name,
+ function_ident,
attrs: proc_attrs,
}));
} else {
@@ -123,12 +123,12 @@ fn collect_custom_derive(
}
}
- fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
+ fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_ident: Ident) {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Attr(ProcMacroDef {
id: item.id,
span: item.span,
- function_name,
+ function_ident,
}));
} else {
let msg = if !self.in_root {
@@ -141,12 +141,12 @@ fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident)
}
}
- fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
+ fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, function_ident: Ident) {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Bang(ProcMacroDef {
id: item.id,
span: item.span,
- function_name,
+ function_ident,
}));
} else {
let msg = if !self.in_root {
@@ -303,7 +303,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
ProcMacro::Derive(m) => m.span,
ProcMacro::Attr(m) | ProcMacro::Bang(m) => m.span,
};
- let local_path = |cx: &ExtCtxt<'_>, name| cx.expr_path(cx.path(span, vec![name]));
+ let local_path = |cx: &ExtCtxt<'_>, ident| cx.expr_path(cx.path(span, vec![ident]));
let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| {
cx.expr_path(cx.path(
span.with_ctxt(harness_span.ctxt()),
@@ -327,7 +327,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
.map(|&s| cx.expr_str(span, s))
.collect::<ThinVec<_>>(),
),
- local_path(cx, cd.function_name),
+ local_path(cx, cd.function_ident),
],
)
}
@@ -345,8 +345,8 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
harness_span,
proc_macro_ty_method_path(cx, ident),
thin_vec![
- cx.expr_str(span, ca.function_name.name),
- local_path(cx, ca.function_name),
+ cx.expr_str(span, ca.function_ident.name),
+ local_path(cx, ca.function_ident),
],
)
}
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 444dc44..00136ac 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -169,8 +169,11 @@ fn produce_final_output_artifacts(
if codegen_results.modules.len() == 1 {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
- let module_name = Some(&codegen_results.modules[0].name[..]);
- let path = crate_output.temp_path(output_type, module_name);
+ let path = crate_output.temp_path_for_cgu(
+ output_type,
+ &codegen_results.modules[0].name,
+ sess.invocation_temp.as_deref(),
+ );
let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() {
sess.dcx()
@@ -183,22 +186,16 @@ fn produce_final_output_artifacts(
ensure_removed(sess.dcx(), &path);
}
} else {
- let extension = crate_output
- .temp_path(output_type, None)
- .extension()
- .unwrap()
- .to_str()
- .unwrap()
- .to_owned();
-
if crate_output.outputs.contains_explicit_name(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
- sess.dcx().emit_warn(ssa_errors::IgnoringEmitPath { extension });
+ sess.dcx()
+ .emit_warn(ssa_errors::IgnoringEmitPath { extension: output_type.extension() });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
- sess.dcx().emit_warn(ssa_errors::IgnoringOutput { extension });
+ sess.dcx()
+ .emit_warn(ssa_errors::IgnoringOutput { extension: output_type.extension() });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
@@ -351,6 +348,7 @@ fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
fn emit_cgu(
output_filenames: &OutputFilenames,
+ invocation_temp: Option<&str>,
prof: &SelfProfilerRef,
name: String,
module: UnwindModule<ObjectModule>,
@@ -366,6 +364,7 @@ fn emit_cgu(
let module_regular = emit_module(
output_filenames,
+ invocation_temp,
prof,
product.object,
ModuleKind::Regular,
@@ -391,6 +390,7 @@ fn emit_cgu(
fn emit_module(
output_filenames: &OutputFilenames,
+ invocation_temp: Option<&str>,
prof: &SelfProfilerRef,
mut object: cranelift_object::object::write::Object<'_>,
kind: ModuleKind,
@@ -409,7 +409,7 @@ fn emit_module(
object.set_section_data(comment_section, producer, 1);
}
- let tmp_file = output_filenames.temp_path(OutputType::Object, Some(&name));
+ let tmp_file = output_filenames.temp_path_for_cgu(OutputType::Object, &name, invocation_temp);
let file = match File::create(&tmp_file) {
Ok(file) => file,
Err(err) => return Err(format!("error creating object file: {}", err)),
@@ -449,8 +449,11 @@ fn reuse_workproduct_for_cgu(
cgu: &CodegenUnit<'_>,
) -> Result<ModuleCodegenResult, String> {
let work_product = cgu.previous_work_product(tcx);
- let obj_out_regular =
- tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
+ let obj_out_regular = tcx.output_filenames(()).temp_path_for_cgu(
+ OutputType::Object,
+ cgu.name().as_str(),
+ tcx.sess.invocation_temp.as_deref(),
+ );
let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
&tcx.sess,
&work_product.saved_files.get("o").expect("no saved object file in work product"),
@@ -595,13 +598,19 @@ fn module_codegen(
let global_asm_object_file =
profiler.generic_activity_with_arg("compile assembly", &*cgu_name).run(|| {
- crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm)
+ crate::global_asm::compile_global_asm(
+ &global_asm_config,
+ &cgu_name,
+ &cx.global_asm,
+ cx.invocation_temp.as_deref(),
+ )
})?;
let codegen_result =
profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| {
emit_cgu(
&global_asm_config.output_filenames,
+ cx.invocation_temp.as_deref(),
&profiler,
cgu_name,
module,
@@ -626,8 +635,11 @@ fn emit_metadata_module(tcx: TyCtxt<'_>, metadata: &EncodedMetadata) -> Compiled
.as_str()
.to_string();
- let tmp_file =
- tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
+ let tmp_file = tcx.output_filenames(()).temp_path_for_cgu(
+ OutputType::Metadata,
+ &metadata_cgu_name,
+ tcx.sess.invocation_temp.as_deref(),
+ );
let symbol_name = rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx);
let obj = create_compressed_metadata_file(tcx.sess, metadata, &symbol_name);
@@ -657,6 +669,7 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
match emit_module(
tcx.output_filenames(()),
+ tcx.sess.invocation_temp.as_deref(),
&tcx.sess.prof,
product.object,
ModuleKind::Allocator,
@@ -728,26 +741,27 @@ pub(crate) fn run_aot(
let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(todo_cgus.len()));
- let modules = tcx.sess.time("codegen mono items", || {
- let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| {
- let dep_node = cgu.codegen_dep_node(tcx);
- tcx.dep_graph
- .with_task(
+ let modules: Vec<_> =
+ tcx.sess.time("codegen mono items", || {
+ let modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| {
+ let dep_node = cgu.codegen_dep_node(tcx);
+ let (module, _) = tcx.dep_graph.with_task(
dep_node,
tcx,
(global_asm_config.clone(), cgu.name(), concurrency_limiter.acquire(tcx.dcx())),
module_codegen,
Some(rustc_middle::dep_graph::hash_result),
- )
- .0
- });
- modules.extend(
- done_cgus
+ );
+ IntoDynSyncSend(module)
+ });
+ modules
.into_iter()
- .map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))),
- );
- modules
- });
+ .map(|module| module.0)
+ .chain(done_cgus.into_iter().map(|(_, cgu)| {
+ OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))
+ }))
+ .collect()
+ });
let allocator_module = emit_allocator_module(tcx);
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index 9ea92c3..79cefb0 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -132,6 +132,7 @@ pub(crate) fn compile_global_asm(
config: &GlobalAsmConfig,
cgu_name: &str,
global_asm: &str,
+ invocation_temp: Option<&str>,
) -> Result<Option<PathBuf>, String> {
if global_asm.is_empty() {
return Ok(None);
@@ -146,7 +147,7 @@ pub(crate) fn compile_global_asm(
global_asm.push('\n');
let global_asm_object_file = add_file_stem_postfix(
- config.output_filenames.temp_path(OutputType::Object, Some(cgu_name)),
+ config.output_filenames.temp_path_for_cgu(OutputType::Object, cgu_name, invocation_temp),
".asm",
);
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index e7afaff..9d9e790 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -124,6 +124,7 @@ fn drop(&mut self) {
/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module).
struct CodegenCx {
output_filenames: Arc<OutputFilenames>,
+ invocation_temp: Option<String>,
should_write_ir: bool,
global_asm: String,
inline_asm_index: usize,
@@ -142,6 +143,7 @@ fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol)
};
CodegenCx {
output_filenames: tcx.output_filenames(()).clone(),
+ invocation_temp: tcx.sess.invocation_temp.clone(),
should_write_ir: crate::pretty_clif::should_write_ir(tcx),
global_asm: String::new(),
inline_asm_index: 0,
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index 6d5df2b..3b48adb 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -104,7 +104,7 @@ fn create_entry_fn(
let termination_trait = tcx.require_lang_item(LangItem::Termination, None);
let report = tcx
.associated_items(termination_trait)
- .find_by_name_and_kind(
+ .find_by_ident_and_kind(
tcx,
Ident::from_str("report"),
AssocKind::Fn,
diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs
index 51c5ba7..16c8953 100644
--- a/compiler/rustc_codegen_gcc/src/back/write.rs
+++ b/compiler/rustc_codegen_gcc/src/back/write.rs
@@ -24,19 +24,23 @@ pub(crate) unsafe fn codegen(
{
let context = &module.module_llvm.context;
- let module_name = module.name.clone();
-
let should_combine_object_files = module.module_llvm.should_combine_object_files;
- let module_name = Some(&module_name[..]);
-
// NOTE: Only generate object files with GIMPLE when this environment variable is set for
// now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit).
// TODO(antoyo): remove this environment variable.
let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1");
- let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
- let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
+ let bc_out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Bitcode,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
+ let obj_out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Object,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
if config.bitcode_needed() {
if fat_lto {
@@ -117,14 +121,22 @@ pub(crate) unsafe fn codegen(
}
if config.emit_ir {
- let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
+ let out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::LlvmAssembly,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
std::fs::write(out, "").expect("write file");
}
if config.emit_asm {
let _timer =
cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name);
- let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
+ let path = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Assembly,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str"));
}
@@ -238,6 +250,7 @@ pub(crate) unsafe fn codegen(
config.emit_asm,
config.emit_ir,
&cgcx.output_filenames,
+ cgcx.invocation_temp.as_deref(),
))
}
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 76d431a..18d221d 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -119,14 +119,18 @@ pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTar
tcx.output_filenames(()).split_dwarf_path(
tcx.sess.split_debuginfo(),
tcx.sess.opts.unstable_opts.split_dwarf_kind,
- Some(mod_name),
+ mod_name,
+ tcx.sess.invocation_temp.as_deref(),
)
} else {
None
};
- let output_obj_file =
- Some(tcx.output_filenames(()).temp_path(OutputType::Object, Some(mod_name)));
+ let output_obj_file = Some(tcx.output_filenames(()).temp_path_for_cgu(
+ OutputType::Object,
+ mod_name,
+ tcx.sess.invocation_temp.as_deref(),
+ ));
let config = TargetMachineFactoryConfig { split_dwarf_file, output_obj_file };
target_machine_factory(
@@ -330,8 +334,11 @@ pub(crate) fn save_temp_bitcode(
return;
}
let ext = format!("{name}.bc");
- let cgu = Some(&module.name[..]);
- let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
+ let path = cgcx.output_filenames.temp_path_ext_for_cgu(
+ &ext,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
write_bitcode_to_file(module, &path)
}
@@ -694,11 +701,12 @@ pub(crate) unsafe fn optimize(
let llcx = &*module.module_llvm.llcx;
let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt);
- let module_name = module.name.clone();
- let module_name = Some(&module_name[..]);
-
if config.emit_no_opt_bc {
- let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
+ let out = cgcx.output_filenames.temp_path_ext_for_cgu(
+ "no-opt.bc",
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
write_bitcode_to_file(module, &out)
}
@@ -743,8 +751,11 @@ pub(crate) unsafe fn optimize(
if let Some(thin_lto_buffer) = thin_lto_buffer {
let thin_lto_buffer = unsafe { ThinBuffer::from_raw_ptr(thin_lto_buffer) };
module.thin_lto_buffer = Some(thin_lto_buffer.data().to_vec());
- let bc_summary_out =
- cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name);
+ let bc_summary_out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::ThinLinkBitcode,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
if config.emit_thin_lto_summary
&& let Some(thin_link_bitcode_filename) = bc_summary_out.file_name()
{
@@ -801,8 +812,6 @@ pub(crate) unsafe fn codegen(
let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
let tm = &*module.module_llvm.tm;
- let module_name = module.name.clone();
- let module_name = Some(&module_name[..]);
let _handlers =
DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::Codegen);
@@ -814,8 +823,16 @@ pub(crate) unsafe fn codegen(
// copy it to the .o file, and delete the bitcode if it wasn't
// otherwise requested.
- let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
- let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
+ let bc_out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Bitcode,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
+ let obj_out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Object,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
if config.bitcode_needed() {
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
@@ -857,7 +874,11 @@ pub(crate) unsafe fn codegen(
if config.emit_ir {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name);
- let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
+ let out = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::LlvmAssembly,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
let out_c = path_to_c_string(&out);
extern "C" fn demangle_callback(
@@ -899,7 +920,11 @@ extern "C" fn demangle_callback(
if config.emit_asm {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name);
- let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
+ let path = cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Assembly,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
// We can't use the same module for asm and object code output,
// because that triggers various errors like invalid IR or broken
@@ -929,7 +954,9 @@ extern "C" fn demangle_callback(
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name);
- let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
+ let dwo_out = cgcx
+ .output_filenames
+ .temp_path_dwo_for_cgu(&module.name, cgcx.invocation_temp.as_deref());
let dwo_out = match (cgcx.split_debuginfo, cgcx.split_dwarf_kind) {
// Don't change how DWARF is emitted when disabled.
(SplitDebuginfo::Off, _) => None,
@@ -994,6 +1021,7 @@ extern "C" fn demangle_callback(
config.emit_asm,
config.emit_ir,
&cgcx.output_filenames,
+ cgcx.invocation_temp.as_deref(),
))
}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 2eaaf12..1eb8f36 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -910,7 +910,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
&& let Some(f) = output_filenames.split_dwarf_path(
tcx.sess.split_debuginfo(),
tcx.sess.opts.unstable_opts.split_dwarf_kind,
- Some(codegen_unit_name),
+ codegen_unit_name,
+ tcx.sess.invocation_temp.as_deref(),
) {
// We get a path relative to the working directory from split_dwarf_path
Some(tcx.sess.source_map().path_mapping().to_real_filename(f))
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 67135fc..d1d6bce 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1421,7 +1421,7 @@ fn vector_mask_to_bitmask<'a, 'll, 'tcx>(
return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
}
- if name == sym::simd_insert {
+ if name == sym::simd_insert || name == sym::simd_insert_dyn {
require!(
in_elem == arg_tys[2],
InvalidMonomorphization::InsertedType {
@@ -1432,40 +1432,49 @@ fn vector_mask_to_bitmask<'a, 'll, 'tcx>(
out_ty: arg_tys[2]
}
);
- let idx = bx
- .const_to_opt_u128(args[1].immediate(), false)
- .expect("typeck should have ensure that this is a const");
- if idx >= in_len.into() {
- return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
- span,
- name,
- arg_idx: 1,
- total_len: in_len.into(),
- });
- }
- return Ok(bx.insert_element(
- args[0].immediate(),
- args[2].immediate(),
- bx.const_i32(idx as i32),
- ));
+
+ let index_imm = if name == sym::simd_insert {
+ let idx = bx
+ .const_to_opt_u128(args[1].immediate(), false)
+ .expect("typeck should have ensure that this is a const");
+ if idx >= in_len.into() {
+ return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
+ span,
+ name,
+ arg_idx: 1,
+ total_len: in_len.into(),
+ });
+ }
+ bx.const_i32(idx as i32)
+ } else {
+ args[1].immediate()
+ };
+
+ return Ok(bx.insert_element(args[0].immediate(), args[2].immediate(), index_imm));
}
- if name == sym::simd_extract {
+ if name == sym::simd_extract || name == sym::simd_extract_dyn {
require!(
ret_ty == in_elem,
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
);
- let idx = bx
- .const_to_opt_u128(args[1].immediate(), false)
- .expect("typeck should have ensure that this is a const");
- if idx >= in_len.into() {
- return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
- span,
- name,
- arg_idx: 1,
- total_len: in_len.into(),
- });
- }
- return Ok(bx.extract_element(args[0].immediate(), bx.const_i32(idx as i32)));
+ let index_imm = if name == sym::simd_extract {
+ let idx = bx
+ .const_to_opt_u128(args[1].immediate(), false)
+ .expect("typeck should have ensure that this is a const");
+ if idx >= in_len.into() {
+ return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
+ span,
+ name,
+ arg_idx: 1,
+ total_len: in_len.into(),
+ });
+ }
+ bx.const_i32(idx as i32)
+ } else {
+ args[1].immediate()
+ };
+
+ return Ok(bx.extract_element(args[0].immediate(), index_imm));
}
if name == sym::simd_select {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 1d05c4e..8de6892 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -112,8 +112,12 @@ pub fn link_binary(
codegen_results.crate_info.local_crate_name,
);
let crate_name = format!("{}", codegen_results.crate_info.local_crate_name);
- let out_filename =
- output.file_for_writing(outputs, OutputType::Exe, Some(crate_name.as_str()));
+ let out_filename = output.file_for_writing(
+ outputs,
+ OutputType::Exe,
+ &crate_name,
+ sess.invocation_temp.as_deref(),
+ );
match crate_type {
CrateType::Rlib => {
let _timer = sess.timer("link_rlib");
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index e816e71..0fd4ed8 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -306,14 +306,18 @@ pub fn new(
cgcx.output_filenames.split_dwarf_path(
cgcx.split_debuginfo,
cgcx.split_dwarf_kind,
- Some(module_name),
+ module_name,
+ cgcx.invocation_temp.as_deref(),
)
} else {
None
};
- let output_obj_file =
- Some(cgcx.output_filenames.temp_path(OutputType::Object, Some(module_name)));
+ let output_obj_file = Some(cgcx.output_filenames.temp_path_for_cgu(
+ OutputType::Object,
+ module_name,
+ cgcx.invocation_temp.as_deref(),
+ ));
TargetMachineFactoryConfig { split_dwarf_file, output_obj_file }
}
}
@@ -344,6 +348,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
pub crate_types: Vec<CrateType>,
pub each_linked_rlib_for_lto: Vec<(CrateNum, PathBuf)>,
pub output_filenames: Arc<OutputFilenames>,
+ pub invocation_temp: Option<String>,
pub regular_module_config: Arc<ModuleConfig>,
pub metadata_module_config: Arc<ModuleConfig>,
pub allocator_module_config: Arc<ModuleConfig>,
@@ -582,8 +587,11 @@ fn produce_final_output_artifacts(
if let [module] = &compiled_modules.modules[..] {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
- let module_name = Some(&module.name[..]);
- let path = crate_output.temp_path(output_type, module_name);
+ let path = crate_output.temp_path_for_cgu(
+ output_type,
+ &module.name,
+ sess.invocation_temp.as_deref(),
+ );
let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() {
sess.dcx()
@@ -596,22 +604,15 @@ fn produce_final_output_artifacts(
ensure_removed(sess.dcx(), &path);
}
} else {
- let extension = crate_output
- .temp_path(output_type, None)
- .extension()
- .unwrap()
- .to_str()
- .unwrap()
- .to_owned();
-
if crate_output.outputs.contains_explicit_name(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
- sess.dcx().emit_warn(errors::IgnoringEmitPath { extension });
+ sess.dcx()
+ .emit_warn(errors::IgnoringEmitPath { extension: output_type.extension() });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
- sess.dcx().emit_warn(errors::IgnoringOutput { extension });
+ sess.dcx().emit_warn(errors::IgnoringOutput { extension: output_type.extension() });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
@@ -967,7 +968,12 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
let dwarf_obj_out = cgcx
.output_filenames
- .split_dwarf_path(cgcx.split_debuginfo, cgcx.split_dwarf_kind, Some(&module.name))
+ .split_dwarf_path(
+ cgcx.split_debuginfo,
+ cgcx.split_dwarf_kind,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ )
.expect(
"saved dwarf object in work product but `split_dwarf_path` returned `None`",
);
@@ -977,7 +983,11 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let mut load_from_incr_cache = |perform, output_type: OutputType| {
if perform {
let saved_file = module.source.saved_files.get(output_type.extension())?;
- let output_path = cgcx.output_filenames.temp_path(output_type, Some(&module.name));
+ let output_path = cgcx.output_filenames.temp_path_for_cgu(
+ output_type,
+ &module.name,
+ cgcx.invocation_temp.as_deref(),
+ );
load_from_incr_comp_dir(output_path, &saved_file)
} else {
None
@@ -1222,6 +1232,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind,
parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend,
pointer_size: tcx.data_layout.pointer_size,
+ invocation_temp: sess.invocation_temp.clone(),
};
// This is the "main loop" of parallel work happening for parallel codegen.
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 1985b3b..12b7a48 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -10,7 +10,7 @@
use rustc_attr_parsing::OptimizeAttr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
-use rustc_data_structures::sync::par_map;
+use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
use rustc_data_structures::unord::UnordMap;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
@@ -640,8 +640,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
let metadata_cgu_name =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
tcx.sess.time("write_compressed_metadata", || {
- let file_name =
- tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
+ let file_name = tcx.output_filenames(()).temp_path_for_cgu(
+ OutputType::Metadata,
+ &metadata_cgu_name,
+ tcx.sess.invocation_temp.as_deref(),
+ );
let data = create_compressed_metadata_file(
tcx.sess,
&metadata,
@@ -757,7 +760,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
let pre_compiled_cgus = par_map(cgus, |(i, _)| {
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
- (i, module)
+ (i, IntoDynSyncSend(module))
});
total_codegen_time += start_time.elapsed();
@@ -777,7 +780,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
match cgu_reuse {
CguReuse::No => {
let (module, cost) = if let Some(cgu) = pre_compiled_cgus.remove(&i) {
- cgu
+ cgu.0
} else {
let start_time = Instant::now();
let module = backend.compile_codegen_unit(tcx, cgu.name());
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index b33de88..42cea5c8 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -277,13 +277,13 @@ pub struct BinaryOutputToTty {
#[derive(Diagnostic)]
#[diag(codegen_ssa_ignoring_emit_path)]
pub struct IgnoringEmitPath {
- pub extension: String,
+ pub extension: &'static str,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_ignoring_output)]
pub struct IgnoringOutput {
- pub extension: String,
+ pub extension: &'static str,
}
#[derive(Diagnostic)]
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 6721792..153935f 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -105,13 +105,19 @@ pub fn into_compiled_module(
emit_asm: bool,
emit_ir: bool,
outputs: &OutputFilenames,
+ invocation_temp: Option<&str>,
) -> CompiledModule {
- let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name)));
- let dwarf_object = emit_dwarf_obj.then(|| outputs.temp_path_dwo(Some(&self.name)));
- let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name)));
- let assembly = emit_asm.then(|| outputs.temp_path(OutputType::Assembly, Some(&self.name)));
- let llvm_ir =
- emit_ir.then(|| outputs.temp_path(OutputType::LlvmAssembly, Some(&self.name)));
+ let object = emit_obj
+ .then(|| outputs.temp_path_for_cgu(OutputType::Object, &self.name, invocation_temp));
+ let dwarf_object =
+ emit_dwarf_obj.then(|| outputs.temp_path_dwo_for_cgu(&self.name, invocation_temp));
+ let bytecode = emit_bc
+ .then(|| outputs.temp_path_for_cgu(OutputType::Bitcode, &self.name, invocation_temp));
+ let assembly = emit_asm
+ .then(|| outputs.temp_path_for_cgu(OutputType::Assembly, &self.name, invocation_temp));
+ let llvm_ir = emit_ir.then(|| {
+ outputs.temp_path_for_cgu(OutputType::LlvmAssembly, &self.name, invocation_temp)
+ });
CompiledModule {
name: self.name.clone(),
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 0758e5d..6a37889 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -3,7 +3,7 @@
use rustc_index::IndexVec;
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::mir::{Local, UnwindTerminateReason, traversal};
+use rustc_middle::mir::{Body, Local, UnwindTerminateReason, traversal};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_middle::{bug, mir, span_bug};
@@ -170,19 +170,29 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) {
assert!(!instance.args.has_infer());
+ let tcx = cx.tcx();
let llfn = cx.get_fn(instance);
- let mir = cx.tcx().instance_mir(instance.def);
+ let mut mir = tcx.instance_mir(instance.def);
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
debug!("fn_abi: {:?}", fn_abi);
- if cx.tcx().codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
+ if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
crate::mir::naked_asm::codegen_naked_asm::<Bx>(cx, &mir, instance);
return;
}
- let debug_context = cx.create_function_debug_context(instance, fn_abi, llfn, mir);
+ if tcx.features().ergonomic_clones() {
+ let monomorphized_mir = instance.instantiate_mir_and_normalize_erasing_regions(
+ tcx,
+ ty::TypingEnv::fully_monomorphized(),
+ ty::EarlyBinder::bind(mir.clone()),
+ );
+ mir = tcx.arena.alloc(optimize_use_clone::<Bx>(cx, monomorphized_mir));
+ }
+
+ let debug_context = cx.create_function_debug_context(instance, fn_abi, llfn, &mir);
let start_llbb = Bx::append_block(cx, llfn, "start");
let mut start_bx = Bx::build(cx, start_llbb);
@@ -194,7 +204,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
let cleanup_kinds =
- base::wants_new_eh_instructions(cx.tcx().sess).then(|| analyze::cleanup_kinds(mir));
+ base::wants_new_eh_instructions(tcx.sess).then(|| analyze::cleanup_kinds(&mir));
let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> =
mir.basic_blocks
@@ -217,7 +227,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cleanup_kinds,
landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
- cold_blocks: find_cold_blocks(cx.tcx(), mir),
+ cold_blocks: find_cold_blocks(tcx, mir),
locals: locals::Locals::empty(),
debug_context,
per_local_var_debug_info: None,
@@ -233,7 +243,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx.compute_per_local_var_debug_info(&mut start_bx).unzip();
fx.per_local_var_debug_info = per_local_var_debug_info;
- let traversal_order = traversal::mono_reachable_reverse_postorder(mir, cx.tcx(), instance);
+ let traversal_order = traversal::mono_reachable_reverse_postorder(mir, tcx, instance);
let memory_locals = analyze::non_ssa_locals(&fx, &traversal_order);
// Allocate variable and temp allocas
@@ -310,6 +320,61 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
+// FIXME: Move this function to mir::transform when post-mono MIR passes land.
+fn optimize_use_clone<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+ cx: &'a Bx::CodegenCx,
+ mut mir: Body<'tcx>,
+) -> Body<'tcx> {
+ let tcx = cx.tcx();
+
+ if tcx.features().ergonomic_clones() {
+ for bb in mir.basic_blocks.as_mut() {
+ let mir::TerminatorKind::Call {
+ args,
+ destination,
+ target,
+ call_source: mir::CallSource::Use,
+ ..
+ } = &bb.terminator().kind
+ else {
+ continue;
+ };
+
+ // CallSource::Use calls always use 1 argument.
+ assert_eq!(args.len(), 1);
+ let arg = &args[0];
+
+ // These types are easily available from locals, so check that before
+ // doing DefId lookups to figure out what we're actually calling.
+ let arg_ty = arg.node.ty(&mir.local_decls, tcx);
+
+ let ty::Ref(_region, inner_ty, mir::Mutability::Not) = *arg_ty.kind() else { continue };
+
+ if !tcx.type_is_copy_modulo_regions(cx.typing_env(), inner_ty) {
+ continue;
+ }
+
+ let Some(arg_place) = arg.node.place() else { continue };
+
+ let destination_block = target.unwrap();
+
+ bb.statements.push(mir::Statement {
+ source_info: bb.terminator().source_info,
+ kind: mir::StatementKind::Assign(Box::new((
+ *destination,
+ mir::Rvalue::Use(mir::Operand::Copy(
+ arg_place.project_deeper(&[mir::ProjectionElem::Deref], tcx),
+ )),
+ ))),
+ });
+
+ bb.terminator_mut().kind = mir::TerminatorKind::Goto { target: destination_block };
+ }
+ }
+
+ mir
+}
+
/// Produces, for each argument, a `Value` pointing at the
/// argument's value. As arguments are places, these are always
/// indirect.
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index fcaf275..f48c73b 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -14,7 +14,7 @@
jobserver_crate = { version = "0.1.28", package = "jobserver" }
measureme = "12.0.1"
rustc-hash = "2.0.0"
-rustc-rayon = { version = "0.5.1", features = ["indexmap"] }
+rustc-rayon-core = { version = "0.5.0" }
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
rustc_arena = { path = "../rustc_arena" }
rustc_graphviz = { path = "../rustc_graphviz" }
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
index 64c64bf..744ae9b 100644
--- a/compiler/rustc_data_structures/src/marker.rs
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -180,6 +180,12 @@ pub fn from(val: T) -> Self {
}
#[inline(always)]
+ pub fn derive<O>(&self, val: O) -> FromDyn<O> {
+ // We already did the check for `sync::is_dyn_thread_safe()` when creating `Self`
+ FromDyn(val)
+ }
+
+ #[inline(always)]
pub fn into_inner(self) -> T {
self.0
}
@@ -200,6 +206,13 @@ fn deref(&self) -> &Self::Target {
}
}
+impl<T> std::ops::DerefMut for FromDyn<T> {
+ #[inline(always)]
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
// A wrapper to convert a struct that is already a `Send` or `Sync` into
// an instance of `DynSend` and `DynSync`, since the compiler cannot infer
// it automatically in some cases. (e.g. Box<dyn Send / Sync>)
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index f63b201..2c62034 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -315,7 +315,7 @@ mod helper {
use super::*;
pub(super) type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
impl<O: ForestObligation> ObligationForest<O> {
- #[cfg_attr(not(bootstrap), define_opaque(ObligationTreeIdGenerator))]
+ #[define_opaque(ObligationTreeIdGenerator)]
pub fn new() -> ObligationForest<O> {
ObligationForest {
nodes: vec![],
diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs
index 9720b22..6338afb 100644
--- a/compiler/rustc_data_structures/src/sync/freeze.rs
+++ b/compiler/rustc_data_structures/src/sync/freeze.rs
@@ -88,7 +88,7 @@ pub fn borrow(&self) -> FreezeReadGuard<'_, T> {
#[inline]
#[track_caller]
pub fn write(&self) -> FreezeWriteGuard<'_, T> {
- self.try_write().expect("still mutable")
+ self.try_write().expect("data should not be frozen if we're still attempting to mutate it")
}
#[inline]
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index 8ef8a3f..ba3c85e 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -7,7 +7,6 @@
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
use parking_lot::Mutex;
-use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
use crate::FatalErrorMarker;
use crate::sync::{DynSend, DynSync, FromDyn, IntoDynSyncSend, mode};
@@ -97,11 +96,11 @@ macro_rules! parallel {
// This function only works when `mode::is_dyn_thread_safe()`.
pub fn scope<'scope, OP, R>(op: OP) -> R
where
- OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
+ OP: FnOnce(&rayon_core::Scope<'scope>) -> R + DynSend,
R: DynSend,
{
let op = FromDyn::from(op);
- rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+ rayon_core::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
}
#[inline]
@@ -114,7 +113,7 @@ pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
let oper_a = FromDyn::from(oper_a);
let oper_b = FromDyn::from(oper_b);
let (a, b) = parallel_guard(|guard| {
- rayon::join(
+ rayon_core::join(
move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
)
@@ -125,56 +124,103 @@ pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
}
}
-pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
+fn par_slice<I: DynSend>(
+ items: &mut [I],
+ guard: &ParallelGuard,
+ for_each: impl Fn(&mut I) + DynSync + DynSend,
+) {
+ struct State<'a, F> {
+ for_each: FromDyn<F>,
+ guard: &'a ParallelGuard,
+ group: usize,
+ }
+
+ fn par_rec<I: DynSend, F: Fn(&mut I) + DynSync + DynSend>(
+ items: &mut [I],
+ state: &State<'_, F>,
+ ) {
+ if items.len() <= state.group {
+ for item in items {
+ state.guard.run(|| (state.for_each)(item));
+ }
+ } else {
+ let (left, right) = items.split_at_mut(items.len() / 2);
+ let mut left = state.for_each.derive(left);
+ let mut right = state.for_each.derive(right);
+ rayon_core::join(move || par_rec(*left, state), move || par_rec(*right, state));
+ }
+ }
+
+ let state = State {
+ for_each: FromDyn::from(for_each),
+ guard,
+ group: std::cmp::max(items.len() / 128, 1),
+ };
+ par_rec(items, &state)
+}
+
+pub fn par_for_each_in<I: DynSend, T: IntoIterator<Item = I>>(
t: T,
- for_each: impl Fn(I) + DynSync + DynSend,
+ for_each: impl Fn(&I) + DynSync + DynSend,
) {
parallel_guard(|guard| {
if mode::is_dyn_thread_safe() {
- let for_each = FromDyn::from(for_each);
- t.into_par_iter().for_each(|i| {
- guard.run(|| for_each(i));
- });
+ let mut items: Vec<_> = t.into_iter().collect();
+ par_slice(&mut items, guard, |i| for_each(&*i))
} else {
t.into_iter().for_each(|i| {
- guard.run(|| for_each(i));
+ guard.run(|| for_each(&i));
});
}
});
}
-pub fn try_par_for_each_in<
- T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
- E: Send,
->(
+/// This runs `for_each` in parallel for each iterator item. If one or more of the
+/// `for_each` calls returns `Err`, the function will also return `Err`. The error returned
+/// will be non-deterministic, but this is expected to be used with `ErrorGuaranteed` which
+/// are all equivalent.
+pub fn try_par_for_each_in<T: IntoIterator, E: DynSend>(
t: T,
- for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
-) -> Result<(), E> {
+ for_each: impl Fn(&<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
+) -> Result<(), E>
+where
+ <T as IntoIterator>::Item: DynSend,
+{
parallel_guard(|guard| {
if mode::is_dyn_thread_safe() {
- let for_each = FromDyn::from(for_each);
- t.into_par_iter()
- .filter_map(|i| guard.run(|| for_each(i)))
- .reduce(|| Ok(()), Result::and)
+ let mut items: Vec<_> = t.into_iter().collect();
+
+ let error = Mutex::new(None);
+
+ par_slice(&mut items, guard, |i| {
+ if let Err(err) = for_each(&*i) {
+ *error.lock() = Some(err);
+ }
+ });
+
+ if let Some(err) = error.into_inner() { Err(err) } else { Ok(()) }
} else {
- t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
+ t.into_iter().filter_map(|i| guard.run(|| for_each(&i))).fold(Ok(()), Result::and)
}
})
}
-pub fn par_map<
- I,
- T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
- R: std::marker::Send,
- C: FromIterator<R> + FromParallelIterator<R>,
->(
+pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterator<R>>(
t: T,
map: impl Fn(I) -> R + DynSync + DynSend,
) -> C {
parallel_guard(|guard| {
if mode::is_dyn_thread_safe() {
let map = FromDyn::from(map);
- t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
+
+ let mut items: Vec<(Option<I>, Option<R>)> =
+ t.into_iter().map(|i| (Some(i), None)).collect();
+
+ par_slice(&mut items, guard, |i| {
+ i.1 = Some(map(i.0.take().unwrap()));
+ });
+
+ items.into_iter().filter_map(|i| i.1).collect()
} else {
t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
}
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 595ac1e..7d9560a 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -264,6 +264,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
hash_untracked_state: None,
register_lints: None,
override_queries: None,
+ extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: diagnostics_registry(),
using_internal_features: &USING_INTERNAL_FEATURES,
@@ -348,10 +349,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
// Make sure name resolution and macro expansion is run.
let _ = tcx.resolver_for_lowering();
- if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
- dump_feature_usage_metrics(tcx, metrics_dir);
- }
-
if callbacks.after_expansion(compiler, tcx) == Compilation::Stop {
return early_exit();
}
@@ -370,6 +367,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
tcx.ensure_ok().analysis(());
+ if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
+ dump_feature_usage_metrics(tcx, metrics_dir);
+ }
+
if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
return early_exit();
}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index e6ff949..9b8131a 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
An intrinsic was declared without being a function.
Erroneous code example:
-```compile_fail,E0622
+```no_run
#![feature(intrinsics)]
#![allow(internal_features)]
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index dfeef5a..2488d87 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -397,7 +397,7 @@ macro_rules! error_codes {
E0619: 0619,
E0620: 0620,
E0621: 0621,
-E0622: 0622,
+E0622: 0622, // REMOVED: rustc-intrinsic ABI was removed
E0623: 0623,
E0624: 0624,
E0625: 0625,
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 39e78ae..3c6df14 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -208,7 +208,7 @@ fn register_functions(bundle: &mut FluentBundle) {
/// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
#[instrument(level = "trace", skip(resources))]
-#[cfg_attr(not(bootstrap), define_opaque(LazyFallbackBundle))]
+#[define_opaque(LazyFallbackBundle)]
pub fn fallback_fluent_bundle(
resources: Vec<&'static str>,
with_directionality_markers: bool,
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index f5f7618..75bb0e8 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -589,7 +589,8 @@ struct DiagCtxtInner {
/// add more information). All stashed diagnostics must be emitted with
/// `emit_stashed_diagnostics` by the time the `DiagCtxtInner` is dropped,
/// otherwise an assertion failure will occur.
- stashed_diagnostics: FxIndexMap<(Span, StashKey), (DiagInner, Option<ErrorGuaranteed>)>,
+ stashed_diagnostics:
+ FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>)>>,
future_breakage_diagnostics: Vec<DiagInner>,
@@ -912,8 +913,12 @@ pub fn stash_diagnostic(
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
// if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
// See the PR for a discussion.
- let key = (span.with_parent(None), key);
- self.inner.borrow_mut().stashed_diagnostics.insert(key, (diag, guar));
+ self.inner
+ .borrow_mut()
+ .stashed_diagnostics
+ .entry(key)
+ .or_default()
+ .insert(span.with_parent(None), (diag, guar));
guar
}
@@ -922,9 +927,10 @@ pub fn stash_diagnostic(
/// and [`StashKey`] as the key. Panics if the found diagnostic is an
/// error.
pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
- let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
- let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key)?;
+ let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
+ |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
+ )?;
assert!(!diag.is_error());
assert!(guar.is_none());
Some(Diag::new_diagnostic(self, diag))
@@ -943,9 +949,10 @@ pub fn try_steal_modify_and_emit_err<F>(
where
F: FnMut(&mut Diag<'_>),
{
- let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
- let err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key);
+ let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
+ |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
+ );
err.map(|(err, guar)| {
// The use of `::<ErrorGuaranteed>` is safe because level is `Level::Error`.
assert_eq!(err.level, Error);
@@ -966,9 +973,10 @@ pub fn try_steal_replace_and_emit_err(
key: StashKey,
new_err: Diag<'_>,
) -> ErrorGuaranteed {
- let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
- let old_err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key);
+ let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
+ |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
+ );
match old_err {
Some((old_err, guar)) => {
assert_eq!(old_err.level, Error);
@@ -983,7 +991,14 @@ pub fn try_steal_replace_and_emit_err(
}
pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
- self.inner.borrow().stashed_diagnostics.get(&(span.with_parent(None), key)).is_some()
+ let inner = self.inner.borrow();
+ if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
+ && !stashed_diagnostics.is_empty()
+ {
+ stashed_diagnostics.contains_key(&span.with_parent(None))
+ } else {
+ false
+ }
}
/// Emit all stashed diagnostics.
@@ -997,7 +1012,11 @@ pub fn err_count(&self) -> usize {
let inner = self.inner.borrow();
inner.err_guars.len()
+ inner.lint_err_guars.len()
- + inner.stashed_diagnostics.values().filter(|(_diag, guar)| guar.is_some()).count()
+ + inner
+ .stashed_diagnostics
+ .values()
+ .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
+ .sum::<usize>()
}
/// This excludes lint errors and delayed bugs. Unless absolutely
@@ -1486,16 +1505,18 @@ fn new(emitter: Box<DynEmitter>) -> Self {
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
let mut guar = None;
let has_errors = !self.err_guars.is_empty();
- for (_, (diag, _guar)) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
- if !diag.is_error() {
- // Unless they're forced, don't flush stashed warnings when
- // there are errors, to avoid causing warning overload. The
- // stash would've been stolen already if it were important.
- if !diag.is_force_warn() && has_errors {
- continue;
+ for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
+ for (_, (diag, _guar)) in stashed_diagnostics {
+ if !diag.is_error() {
+ // Unless they're forced, don't flush stashed warnings when
+ // there are errors, to avoid causing warning overload. The
+ // stash would've been stolen already if it were important.
+ if !diag.is_force_warn() && has_errors {
+ continue;
+ }
}
+ guar = guar.or(self.emit_diagnostic(diag, None));
}
- guar = guar.or(self.emit_diagnostic(diag, None));
}
guar
}
@@ -1688,6 +1709,7 @@ fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
if let Some((_diag, guar)) = self
.stashed_diagnostics
.values()
+ .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
.find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
{
*guar
@@ -1700,13 +1722,9 @@ fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
|| {
- if let Some((_diag, guar)) =
- self.stashed_diagnostics.values().find(|(_diag, guar)| guar.is_some())
- {
- *guar
- } else {
- None
- }
+ self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
+ stashed_diagnostics.values().find_map(|(_, guar)| *guar)
+ })
},
)
}
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index d14e476..49f6d58 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1102,7 +1102,7 @@ fn macro_accessible(
/// HIR proc macros items back to their harness items.
fn declare_proc_macro(&mut self, id: NodeId);
- fn append_stripped_cfg_item(&mut self, parent_node: NodeId, name: Ident, cfg: ast::MetaItem);
+ fn append_stripped_cfg_item(&mut self, parent_node: NodeId, ident: Ident, cfg: ast::MetaItem);
/// Tools registered with `#![register_tool]` and used by tool attributes and lints.
fn registered_tools(&self) -> &RegisteredTools;
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index bca846d..1b53947 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1169,9 +1169,9 @@ fn expand_cfg_false(
collector.cx.dcx().emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
}
- /// All of the names (items) declared by this node.
+ /// All of the identifiers (items) declared by this node.
/// This is an approximation and should only be used for diagnostics.
- fn declared_names(&self) -> Vec<Ident> {
+ fn declared_idents(&self) -> Vec<Ident> {
vec![]
}
}
@@ -1306,7 +1306,7 @@ fn wrap_flat_map_node_walk_flat_map(
res
}
- fn declared_names(&self) -> Vec<Ident> {
+ fn declared_idents(&self) -> Vec<Ident> {
if let ItemKind::Use(ut) = &self.kind {
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
match &ut.kind {
@@ -2061,10 +2061,10 @@ fn flat_map_node<Node: InvocationCollectorNode<OutputTy: Default>>(
}
if let Some(meta_item) = meta_item {
- for name in node.declared_names() {
+ for ident in node.declared_idents() {
self.cx.resolver.append_stripped_cfg_item(
self.cx.current_expansion.lint_node_id,
- name,
+ ident,
meta_item.clone(),
)
}
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 88e6593..8968c17 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -63,7 +63,7 @@ macro_rules! declare_features {
/// Allows using `const` operands in inline assembly.
(accepted, asm_const, "1.82.0", Some(93332)),
/// Allows using `label` operands in inline assembly.
- (accepted, asm_goto, "CURRENT_RUSTC_VERSION", Some(119364)),
+ (accepted, asm_goto, "1.87.0", Some(119364)),
/// Allows using `sym` operands in inline assembly.
(accepted, asm_sym, "1.66.0", Some(93333)),
/// Allows the definition of associated constants in `trait` or `impl` blocks.
@@ -332,7 +332,7 @@ macro_rules! declare_features {
/// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args.
(accepted, precise_capturing, "1.82.0", Some(123432)),
/// Allows `use<..>` precise capturign on impl Trait in traits.
- (accepted, precise_capturing_in_traits, "CURRENT_RUSTC_VERSION", Some(130044)),
+ (accepted, precise_capturing_in_traits, "1.87.0", Some(130044)),
/// Allows procedural macros in `proc-macro` crates.
(accepted, proc_macro, "1.29.0", Some(38356)),
/// Allows multi-segment paths in attributes and derives.
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 6ba7b22..402e18c 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -247,7 +247,7 @@ macro_rules! declare_features {
/// Allows unnamed fields of struct and union type
(removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")),
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
- (removed, unsized_tuple_coercion, "CURRENT_RUSTC_VERSION", Some(42877),
+ (removed, unsized_tuple_coercion, "1.87.0", Some(42877),
Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")),
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
(removed, untagged_unions, "1.13.0", Some(55149),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 7edb05c..98213af 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -474,7 +474,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows `dyn* Trait` objects.
(incomplete, dyn_star, "1.65.0", Some(102425)),
/// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }`
- (incomplete, ergonomic_clones, "CURRENT_RUSTC_VERSION", Some(132290)),
+ (incomplete, ergonomic_clones, "1.87.0", Some(132290)),
/// Allows exhaustive pattern matching on types that contain uninhabited types.
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
/// Allows explicit tail calls via `become` expression.
@@ -511,7 +511,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows generic parameters and where-clauses on free & associated const items.
(incomplete, generic_const_items, "1.73.0", Some(113521)),
/// Allows the type of const generics to depend on generic parameters
- (incomplete, generic_const_parameter_types, "CURRENT_RUSTC_VERSION", Some(137626)),
+ (incomplete, generic_const_parameter_types, "1.87.0", Some(137626)),
/// Allows any generic constants being used as pattern type range ends
(incomplete, generic_pattern_types, "1.86.0", Some(136574)),
/// Allows registering static items globally, possibly across crates, to iterate over at runtime.
@@ -602,7 +602,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows the use of raw-dylibs on ELF platforms
- (incomplete, raw_dylib_elf, "CURRENT_RUSTC_VERSION", Some(135694)),
+ (incomplete, raw_dylib_elf, "1.87.0", Some(135694)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant
@@ -664,14 +664,14 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
(unstable, used_with_arg, "1.60.0", Some(93798)),
/// Allows use of attributes in `where` clauses.
- (unstable, where_clause_attrs, "CURRENT_RUSTC_VERSION", Some(115590)),
+ (unstable, where_clause_attrs, "1.87.0", Some(115590)),
/// Allows use of x86 `AMX` target-feature attributes and intrinsics
(unstable, x86_amx_intrinsics, "1.81.0", Some(126622)),
/// Allows use of the `xop` target-feature
(unstable, xop_target_feature, "1.81.0", Some(127208)),
/// Allows `do yeet` expressions
(unstable, yeet_expr, "1.62.0", Some(96373)),
- (unstable, yield_expr, "CURRENT_RUSTC_VERSION", Some(43122)),
+ (unstable, yield_expr, "1.87.0", Some(43122)),
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!
// Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index c614779..c9c4936 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3399,9 +3399,9 @@ pub struct BareFnTy<'hir> {
pub abi: ExternAbi,
pub generic_params: &'hir [GenericParam<'hir>],
pub decl: &'hir FnDecl<'hir>,
- // `Option` because bare fn parameter names are optional. We also end up
+ // `Option` because bare fn parameter identifiers are optional. We also end up
// with `None` in some error cases, e.g. invalid parameter patterns.
- pub param_names: &'hir [Option<Ident>],
+ pub param_idents: &'hir [Option<Ident>],
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index ea3f396..93d20df 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -652,10 +652,10 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_ident(foreign_item.ident));
match foreign_item.kind {
- ForeignItemKind::Fn(ref sig, param_names, ref generics) => {
+ ForeignItemKind::Fn(ref sig, param_idents, ref generics) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_decl(sig.decl));
- for ident in param_names.iter().copied() {
+ for ident in param_idents.iter().copied() {
visit_opt!(visitor, visit_ident, ident);
}
}
@@ -1169,9 +1169,9 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_ty_unambig(ty));
visit_opt!(visitor, visit_nested_body, default);
}
- TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
+ TraitItemKind::Fn(ref sig, TraitFn::Required(param_idents)) => {
try_visit!(visitor.visit_fn_decl(sig.decl));
- for ident in param_names.iter().copied() {
+ for ident in param_idents.iter().copied() {
visit_opt!(visitor, visit_ident, ident);
}
}
diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs
index 0837444..18c2bfd 100644
--- a/compiler/rustc_hir/src/tests.rs
+++ b/compiler/rustc_hir/src/tests.rs
@@ -17,7 +17,7 @@ fn def_path_hash_depends_on_crate_id() {
// the crate by changing the crate disambiguator (e.g. via bumping the
// crate's version number).
- create_session_globals_then(Edition::Edition2024, None, || {
+ create_session_globals_then(Edition::Edition2024, &[], None, || {
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 2f7c3cb..92701e3 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -1,5 +1,5 @@
-hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$qself}`
- .label = ambiguous associated {$assoc_kind} `{$assoc_name}`
+hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_ident}` in bounds of `{$qself}`
+ .label = ambiguous associated {$assoc_kind} `{$assoc_ident}`
hir_analysis_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
@@ -12,13 +12,13 @@
.label = private {$kind}
.defined_here_label = the {$kind} is defined here
-hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$qself}`
+hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_ident}` not found for `{$qself}`
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
[true] an
*[false] a similarly named
} associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
-hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
+hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_ident}` not found
hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg =
consider fully qualifying{$identically_named ->
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 18ef00d..f50746d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -719,7 +719,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
def_id,
tcx.def_ident_span(def_id).unwrap(),
i.name,
- ExternAbi::Rust,
)
}
}
@@ -787,16 +786,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
for item in items {
let def_id = item.id.owner_id.def_id;
- if tcx.has_attr(def_id, sym::rustc_intrinsic) {
- intrinsic::check_intrinsic_type(
- tcx,
- item.id.owner_id.def_id,
- item.span,
- item.ident.name,
- abi,
- );
- }
-
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.own_params.len() - own_counts.lifetimes != 0 {
@@ -937,31 +926,7 @@ fn check_impl_items_against_trait<'tcx>(
let trait_def = tcx.trait_def(trait_ref.def_id);
- let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis());
-
- let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
- let cause = ObligationCause::misc(tcx.def_span(impl_id), impl_id);
- let param_env = tcx.param_env(impl_id);
-
- let self_is_guaranteed_unsized = match tcx
- .struct_tail_raw(
- trait_ref.self_ty(),
- |ty| {
- ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| {
- Ty::new_error_with_message(
- tcx,
- tcx.def_span(impl_id),
- "struct tail should be computable",
- )
- })
- },
- || (),
- )
- .kind()
- {
- ty::Dynamic(_, _, ty::DynKind::Dyn) | ty::Slice(_) | ty::Str => true,
- _ => false,
- };
+ let self_is_guaranteed_unsize_self = tcx.impl_self_is_guaranteed_unsized(impl_id);
for &impl_item in impl_item_refs {
let ty_impl_item = tcx.associated_item(impl_item);
@@ -992,7 +957,7 @@ fn check_impl_items_against_trait<'tcx>(
}
}
- if self_is_guaranteed_unsized && tcx.generics_require_sized_self(ty_trait_item.def_id) {
+ if self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(ty_trait_item.def_id) {
tcx.emit_node_span_lint(
rustc_lint_defs::builtin::DEAD_CODE,
tcx.local_def_id_to_hir_id(ty_impl_item.def_id.expect_local()),
@@ -1027,7 +992,7 @@ fn check_impl_items_against_trait<'tcx>(
if !is_implemented
&& tcx.defaultness(impl_id).is_final()
// unsized types don't need to implement methods that have `Self: Sized` bounds.
- && !(self_is_guaranteed_unsized && tcx.generics_require_sized_self(trait_item_id))
+ && !(self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(trait_item_id))
{
missing_items.push(tcx.associated_item(trait_item_id));
}
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 32a8f10..29a9931 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1046,11 +1046,11 @@ fn report_trait_method_mismatch<'tcx>(
// argument pattern and type.
let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let span = tcx
- .hir_body_param_names(body)
+ .hir_body_param_idents(body)
.zip(sig.decl.inputs.iter())
- .map(|(param_name, ty)| {
- if let Some(param_name) = param_name {
- param_name.span.to(ty.span)
+ .map(|(param_ident, ty)| {
+ if let Some(param_ident) = param_ident {
+ param_ident.span.to(ty.span)
} else {
ty.span
}
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 0bf9e12..ed8ca27 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -1,9 +1,8 @@
//! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.
use rustc_abi::ExternAbi;
-use rustc_errors::codes::*;
-use rustc_errors::{DiagMessage, struct_span_code_err};
-use rustc_hir::{self as hir, Safety};
+use rustc_errors::DiagMessage;
+use rustc_hir::{self as hir};
use rustc_middle::bug;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -26,17 +25,10 @@ fn equate_intrinsic_type<'tcx>(
sig: ty::PolyFnSig<'tcx>,
) {
let (generics, span) = match tcx.hir_node_by_def_id(def_id) {
- hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. })
- | hir::Node::ForeignItem(hir::ForeignItem {
- kind: hir::ForeignItemKind::Fn(_, _, generics),
- ..
- }) => (tcx.generics_of(def_id), generics.span),
- _ => {
- struct_span_code_err!(tcx.dcx(), span, E0622, "intrinsic must be a function")
- .with_span_label(span, "expected a function")
- .emit();
- return;
+ hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) => {
+ (tcx.generics_of(def_id), generics.span)
}
+ _ => tcx.dcx().span_bug(span, "intrinsic must be a function"),
};
let own_counts = generics.own_counts();
@@ -70,13 +62,7 @@ fn equate_intrinsic_type<'tcx>(
}
/// Returns the unsafety of the given intrinsic.
-pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
- let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
- tcx.fn_sig(intrinsic_id).skip_binder().safety()
- } else {
- // Old-style intrinsics are never safe
- Safety::Unsafe
- };
+fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
// When adding a new intrinsic to this list,
// it's usually worth updating that intrinsic's documentation
@@ -148,7 +134,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
_ => hir::Safety::Unsafe,
};
- if has_safe_attr != is_in_list {
+ if tcx.fn_sig(intrinsic_id).skip_binder().safety() != is_in_list {
tcx.dcx().struct_span_err(
tcx.def_span(intrinsic_id),
DiagMessage::from(format!(
@@ -163,12 +149,11 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
/// and in `library/core/src/intrinsics.rs`.
-pub fn check_intrinsic_type(
+pub(crate) fn check_intrinsic_type(
tcx: TyCtxt<'_>,
intrinsic_id: LocalDefId,
span: Span,
intrinsic_name: Symbol,
- abi: ExternAbi,
) {
let generics = tcx.generics_of(intrinsic_id);
let param = |n| {
@@ -674,8 +659,12 @@ pub fn check_intrinsic_type(
sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
- sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
- sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
+ sym::simd_insert | sym::simd_insert_dyn => {
+ (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0))
+ }
+ sym::simd_extract | sym::simd_extract_dyn => {
+ (2, 0, vec![param(0), tcx.types.u32], param(1))
+ }
sym::simd_cast
| sym::simd_as
| sym::simd_cast_ptr
@@ -706,7 +695,7 @@ pub fn check_intrinsic_type(
};
(n_tps, 0, n_cts, inputs, output, safety)
};
- let sig = tcx.mk_fn_sig(inputs, output, false, safety, abi);
+ let sig = tcx.mk_fn_sig(inputs, output, false, safety, ExternAbi::Rust);
let sig = ty::Binder::bind_with_vars(sig, bound_vars);
equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig)
}
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 69b921f..deded69 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -439,9 +439,9 @@ fn probe_ty_param_bounds(
&self,
span: Span,
def_id: LocalDefId,
- assoc_name: Ident,
+ assoc_ident: Ident,
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
- self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
+ self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_ident))
}
fn lower_assoc_shared(
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index e90a1cc..ce0f83d 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -584,12 +584,12 @@ pub(super) fn explicit_super_predicates_of<'tcx>(
pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
tcx: TyCtxt<'tcx>,
- (trait_def_id, assoc_name): (DefId, Ident),
+ (trait_def_id, assoc_ident): (DefId, Ident),
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
implied_predicates_with_filter(
tcx,
trait_def_id,
- PredicateFilter::SelfTraitThatDefines(assoc_name),
+ PredicateFilter::SelfTraitThatDefines(assoc_ident),
)
}
@@ -617,7 +617,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
filter: PredicateFilter,
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
let Some(trait_def_id) = trait_def_id.as_local() else {
- // if `assoc_name` is None, then the query should've been redirected to an
+ // if `assoc_ident` is None, then the query should've been redirected to an
// external provider
assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_));
return tcx.explicit_super_predicates_of(trait_def_id);
@@ -834,11 +834,11 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
#[instrument(level = "trace", skip(tcx))]
pub(super) fn type_param_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
- (item_def_id, def_id, assoc_name): (LocalDefId, LocalDefId, Ident),
+ (item_def_id, def_id, assoc_ident): (LocalDefId, LocalDefId, Ident),
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
- return tcx.type_param_predicates((opaque_def_id.expect_local(), def_id, assoc_name));
+ return tcx.type_param_predicates((opaque_def_id.expect_local(), def_id, assoc_ident));
}
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
unreachable!("should not be lowering bounds on RPITIT in impl")
@@ -863,7 +863,7 @@ pub(super) fn type_param_predicates<'tcx>(
let result = if let Some(parent) = parent {
let icx = ItemCtxt::new(tcx, parent);
- icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
+ icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_ident)
} else {
ty::EarlyBinder::bind(&[] as &[_])
};
@@ -889,7 +889,7 @@ pub(super) fn type_param_predicates<'tcx>(
let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(
hir_generics,
def_id,
- PredicateFilter::SelfTraitThatDefines(assoc_name),
+ PredicateFilter::SelfTraitThatDefines(assoc_ident),
));
let bounds =
@@ -908,7 +908,7 @@ pub(super) fn type_param_predicates<'tcx>(
_ => unreachable!(),
};
assert_only_contains_predicates_from(
- PredicateFilter::SelfTraitThatDefines(assoc_name),
+ PredicateFilter::SelfTraitThatDefines(assoc_ident),
bounds,
self_ty,
);
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 4047538..9bcda35 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1874,13 +1874,13 @@ fn visit_segment_args(
fn supertrait_hrtb_vars(
tcx: TyCtxt<'tcx>,
def_id: DefId,
- assoc_name: Ident,
+ assoc_ident: Ident,
assoc_kind: ty::AssocKind,
) -> Option<(Vec<ty::BoundVariableKind>, &'tcx ty::AssocItem)> {
let trait_defines_associated_item_named = |trait_def_id: DefId| {
- tcx.associated_items(trait_def_id).find_by_name_and_kind(
+ tcx.associated_items(trait_def_id).find_by_ident_and_kind(
tcx,
- assoc_name,
+ assoc_ident,
assoc_kind,
trait_def_id,
)
@@ -1904,7 +1904,7 @@ fn supertrait_hrtb_vars(
if let Some(assoc_item) = trait_defines_associated_item_named(def_id) {
break Some((bound_vars.into_iter().collect(), assoc_item));
}
- let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_name));
+ let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_ident));
let obligations = predicates.iter_identity_copied().filter_map(|(pred, _)| {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index e6090a1..508970c 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -23,7 +23,7 @@ pub(crate) struct AmbiguousAssocItem<'a> {
#[label]
pub span: Span,
pub assoc_kind: &'static str,
- pub assoc_name: Ident,
+ pub assoc_ident: Ident,
pub qself: &'a str,
}
@@ -75,7 +75,7 @@ pub(crate) struct AssocItemIsPrivate {
pub(crate) struct AssocItemNotFound<'a> {
#[primary_span]
pub span: Span,
- pub assoc_name: Ident,
+ pub assoc_ident: Ident,
pub assoc_kind: &'static str,
pub qself: &'a str,
#[subdiagnostic]
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 55087d1..24d05b4 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -363,10 +363,10 @@ pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<
for hir_bound in hir_bounds {
// In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
// we skip over any traits that don't define the given associated type.
- if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
+ if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter {
if let Some(trait_ref) = hir_bound.trait_ref()
&& let Some(trait_did) = trait_ref.trait_def_id()
- && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
+ && self.tcx().trait_may_define_assoc_item(trait_did, assoc_ident)
{
// Okay
} else {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index ecb453b..d1ee5a5 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -49,13 +49,13 @@ pub(crate) fn validate_cmse_abi<'tcx>(
Ok(Err(index)) => {
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
// ^^^^^^
- let span = if let Some(ident) = bare_fn_ty.param_names[index] {
+ let span = if let Some(ident) = bare_fn_ty.param_idents[index] {
ident.span.to(bare_fn_ty.decl.inputs[index].span)
} else {
bare_fn_ty.decl.inputs[index].span
}
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
- let plural = bare_fn_ty.param_names.len() - index != 1;
+ let plural = bare_fn_ty.param_idents.len() - index != 1;
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi });
}
Err(layout_err) => {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 6e9c178..5a0524d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -117,7 +117,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
all_candidates: impl Fn() -> I,
qself: AssocItemQSelf,
assoc_kind: ty::AssocKind,
- assoc_name: Ident,
+ assoc_ident: Ident,
span: Span,
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
) -> ErrorGuaranteed
@@ -129,11 +129,15 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
// First and foremost, provide a more user-friendly & “intuitive” error on kind mismatches.
if let Some(assoc_item) = all_candidates().find_map(|r| {
tcx.associated_items(r.def_id())
- .filter_by_name_unhygienic(assoc_name.name)
- .find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
+ .filter_by_name_unhygienic(assoc_ident.name)
+ .find(|item| tcx.hygienic_eq(assoc_ident, item.ident(tcx), r.def_id()))
}) {
return self.complain_about_assoc_kind_mismatch(
- assoc_item, assoc_kind, assoc_name, span, constraint,
+ assoc_item,
+ assoc_kind,
+ assoc_ident,
+ span,
+ constraint,
);
}
@@ -142,18 +146,18 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
// valid span, so we point at the whole path segment instead.
- let is_dummy = assoc_name.span == DUMMY_SP;
+ let is_dummy = assoc_ident.span == DUMMY_SP;
let mut err = errors::AssocItemNotFound {
- span: if is_dummy { span } else { assoc_name.span },
- assoc_name,
+ span: if is_dummy { span } else { assoc_ident.span },
+ assoc_ident,
assoc_kind: assoc_kind_str,
qself: &qself_str,
label: None,
sugg: None,
// Try to get the span of the identifier within the path's syntax context
// (if that's different).
- within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()),
+ within_macro_span: assoc_ident.span.within_macro(span, tcx.sess.source_map()),
};
if is_dummy {
@@ -169,10 +173,10 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
.collect();
if let Some(suggested_name) =
- find_best_match_for_name(&all_candidate_names, assoc_name.name, None)
+ find_best_match_for_name(&all_candidate_names, assoc_ident.name, None)
{
err.sugg = Some(errors::AssocItemNotFoundSugg::Similar {
- span: assoc_name.span,
+ span: assoc_ident.span,
assoc_kind: assoc_kind_str,
suggested_name,
});
@@ -201,7 +205,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
.collect();
if let Some(suggested_name) =
- find_best_match_for_name(&wider_candidate_names, assoc_name.name, None)
+ find_best_match_for_name(&wider_candidate_names, assoc_ident.name, None)
{
if let [best_trait] = visible_traits
.iter()
@@ -215,11 +219,11 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
{
let trait_name = tcx.def_path_str(best_trait);
err.label = Some(errors::AssocItemNotFoundLabel::FoundInOtherTrait {
- span: assoc_name.span,
+ span: assoc_ident.span,
assoc_kind: assoc_kind_str,
trait_name: &trait_name,
suggested_name,
- identically_named: suggested_name == assoc_name.name,
+ identically_named: suggested_name == assoc_ident.name,
});
if let AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span) = qself
// Not using `self.item_def_id()` here as that would yield the opaque type itself if we're
@@ -246,7 +250,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
// The type param already has a bound for `trait_name`, we just need to
// change the associated item.
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
- span: assoc_name.span,
+ span: assoc_ident.span,
assoc_kind: assoc_kind_str,
suggested_name,
});
@@ -265,7 +269,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
Applicability::MaybeIncorrect
};
- let identically_named = suggested_name == assoc_name.name;
+ let identically_named = suggested_name == assoc_ident.name;
if let DefKind::TyAlias = tcx.def_kind(item_def_id)
&& !tcx.type_alias_is_lazy(item_def_id)
@@ -273,7 +277,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTraitQPath {
lo: ty_param_span.shrink_to_lo(),
mi: ty_param_span.shrink_to_hi(),
- hi: (!identically_named).then_some(assoc_name.span),
+ hi: (!identically_named).then_some(assoc_ident.span),
trait_ref,
identically_named,
suggested_name,
@@ -294,7 +298,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
// We suggested constraining a type parameter, but the associated item on it
// was also not an exact match, so we also suggest changing it.
err.span_suggestion_verbose(
- assoc_name.span,
+ assoc_ident.span,
fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
suggested_name,
Applicability::MaybeIncorrect,
@@ -311,13 +315,13 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
// suggest using it.
if let [candidate_name] = all_candidate_names.as_slice() {
err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
- span: assoc_name.span,
+ span: assoc_ident.span,
qself: &qself_str,
assoc_kind: assoc_kind_str,
suggested_name: *candidate_name,
});
} else {
- err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_name.span });
+ err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_ident.span });
}
self.dcx().emit_err(err)
@@ -805,7 +809,7 @@ pub(crate) fn check_for_required_assoc_tys(
return None;
};
- let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
+ let assoc_item = tcx.associated_items(trait_def).find_by_ident_and_kind(
tcx,
ident,
ty::AssocKind::Type,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index b4a71ed..83aa0d9 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -147,7 +147,7 @@ fn probe_ty_param_bounds(
&self,
span: Span,
def_id: LocalDefId,
- assoc_name: Ident,
+ assoc_ident: Ident,
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
/// Lower an associated type/const (from a trait) to a projection.
@@ -933,11 +933,11 @@ fn probe_trait_that_defines_assoc_item(
&self,
trait_def_id: DefId,
assoc_kind: ty::AssocKind,
- assoc_name: Ident,
+ assoc_ident: Ident,
) -> bool {
self.tcx()
.associated_items(trait_def_id)
- .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id)
+ .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_kind, trait_def_id)
.is_some()
}
@@ -964,7 +964,7 @@ fn lower_path_segment(
}
/// Search for a trait bound on a type parameter whose trait defines the associated item
- /// given by `assoc_name` and `kind`.
+ /// given by `assoc_ident` and `kind`.
///
/// This fails if there is no such bound in the list of candidates or if there are multiple
/// candidates in which case it reports ambiguity.
@@ -976,13 +976,13 @@ fn probe_single_ty_param_bound_for_assoc_item(
ty_param_def_id: LocalDefId,
ty_param_span: Span,
kind: ty::AssocKind,
- assoc_name: Ident,
+ assoc_ident: Ident,
span: Span,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
- debug!(?ty_param_def_id, ?assoc_name, ?span);
+ debug!(?ty_param_def_id, ?assoc_ident, ?span);
let tcx = self.tcx();
- let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name);
+ let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
debug!("predicates={:#?}", predicates);
self.probe_single_bound_for_assoc_item(
@@ -990,17 +990,18 @@ fn probe_single_ty_param_bound_for_assoc_item(
let trait_refs = predicates
.iter_identity_copied()
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
- traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
+ traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
},
AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
kind,
- assoc_name,
+ assoc_ident,
span,
None,
)
}
- /// Search for a single trait bound whose trait defines the associated item given by `assoc_name`.
+ /// Search for a single trait bound whose trait defines the associated item given by
+ /// `assoc_ident`.
///
/// This fails if there is no such bound in the list of candidates or if there are multiple
/// candidates in which case it reports ambiguity.
@@ -1010,7 +1011,7 @@ fn probe_single_bound_for_assoc_item<I>(
all_candidates: impl Fn() -> I,
qself: AssocItemQSelf,
assoc_kind: ty::AssocKind,
- assoc_name: Ident,
+ assoc_ident: Ident,
span: Span,
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
@@ -1020,7 +1021,7 @@ fn probe_single_bound_for_assoc_item<I>(
let tcx = self.tcx();
let mut matching_candidates = all_candidates().filter(|r| {
- self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_name)
+ self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_ident)
});
let Some(bound) = matching_candidates.next() else {
@@ -1028,7 +1029,7 @@ fn probe_single_bound_for_assoc_item<I>(
all_candidates,
qself,
assoc_kind,
- assoc_name,
+ assoc_ident,
span,
constraint,
);
@@ -1044,7 +1045,7 @@ fn probe_single_bound_for_assoc_item<I>(
let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
span,
assoc_kind: assoc_kind_str,
- assoc_name,
+ assoc_ident,
qself: &qself_str,
});
// Provide a more specific error code index entry for equality bindings.
@@ -1065,13 +1066,13 @@ fn probe_single_bound_for_assoc_item<I>(
let bound_id = bound.def_id();
let bound_span = tcx
.associated_items(bound_id)
- .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
+ .find_by_ident_and_kind(tcx, assoc_ident, assoc_kind, bound_id)
.and_then(|item| tcx.hir_span_if_local(item.def_id));
if let Some(bound_span) = bound_span {
err.span_label(
bound_span,
- format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
+ format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
);
if let Some(constraint) = constraint {
match constraint.kind {
@@ -1087,7 +1088,7 @@ fn probe_single_bound_for_assoc_item<I>(
}
// FIXME(#97583): This isn't syntactically well-formed!
where_bounds.push(format!(
- " T: {trait}::{assoc_name} = {term}",
+ " T: {trait}::{assoc_ident} = {term}",
trait = bound.print_only_trait_path(),
));
}
@@ -1096,7 +1097,7 @@ trait = bound.print_only_trait_path(),
}
} else {
err.span_suggestion_verbose(
- span.with_hi(assoc_name.span.lo()),
+ span.with_hi(assoc_ident.span.lo()),
"use fully-qualified syntax to disambiguate",
format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
Applicability::MaybeIncorrect,
@@ -1104,7 +1105,7 @@ trait = bound.print_only_trait_path(),
}
} else {
err.note(format!(
- "associated {assoc_kind_str} `{assoc_name}` could derive from `{}`",
+ "associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`",
bound.print_only_trait_path(),
));
}
@@ -2858,7 +2859,7 @@ pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
- let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
+ let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
tcx,
*ident,
ty::AssocKind::Fn,
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 865209b..e5ab317 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -397,7 +397,7 @@ fn print_type(&mut self, ty: &hir::Ty<'_>) {
self.pclose();
}
hir::TyKind::BareFn(f) => {
- self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_names);
+ self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_idents);
}
hir::TyKind::UnsafeBinder(unsafe_binder) => {
self.print_unsafe_binder(unsafe_binder);
@@ -473,14 +473,14 @@ fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
self.maybe_print_comment(item.span.lo());
self.print_attrs_as_outer(self.attrs(item.hir_id()));
match item.kind {
- hir::ForeignItemKind::Fn(sig, arg_names, generics) => {
+ hir::ForeignItemKind::Fn(sig, arg_idents, generics) => {
self.head("");
self.print_fn(
sig.decl,
sig.header,
Some(item.ident.name),
generics,
- arg_names,
+ arg_idents,
None,
);
self.end(); // end head-ibox
@@ -899,10 +899,10 @@ fn print_method_sig(
ident: Ident,
m: &hir::FnSig<'_>,
generics: &hir::Generics<'_>,
- arg_names: &[Option<Ident>],
+ arg_idents: &[Option<Ident>],
body_id: Option<hir::BodyId>,
) {
- self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_names, body_id);
+ self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_idents, body_id);
}
fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
@@ -914,8 +914,8 @@ fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
hir::TraitItemKind::Const(ty, default) => {
self.print_associated_const(ti.ident, ti.generics, ty, default);
}
- hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_names)) => {
- self.print_method_sig(ti.ident, sig, ti.generics, arg_names, None);
+ hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_idents)) => {
+ self.print_method_sig(ti.ident, sig, ti.generics, arg_idents, None);
self.word(";");
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
@@ -2122,7 +2122,7 @@ fn print_fn(
header: hir::FnHeader,
name: Option<Symbol>,
generics: &hir::Generics<'_>,
- arg_names: &[Option<Ident>],
+ arg_idents: &[Option<Ident>],
body_id: Option<hir::BodyId>,
) {
self.print_fn_header_info(header);
@@ -2134,16 +2134,16 @@ fn print_fn(
self.print_generic_params(generics.params);
self.popen();
- // Make sure we aren't supplied *both* `arg_names` and `body_id`.
- assert!(arg_names.is_empty() || body_id.is_none());
+ // Make sure we aren't supplied *both* `arg_idents` and `body_id`.
+ assert!(arg_idents.is_empty() || body_id.is_none());
let mut i = 0;
let mut print_arg = |s: &mut Self, ty: Option<&hir::Ty<'_>>| {
if i == 0 && decl.implicit_self.has_implicit_self() {
s.print_implicit_self(&decl.implicit_self);
} else {
- if let Some(arg_name) = arg_names.get(i) {
- if let Some(arg_name) = arg_name {
- s.word(arg_name.to_string());
+ if let Some(arg_ident) = arg_idents.get(i) {
+ if let Some(arg_ident) = arg_ident {
+ s.word(arg_ident.to_string());
s.word(":");
s.space();
}
@@ -2452,7 +2452,7 @@ fn print_ty_fn(
decl: &hir::FnDecl<'_>,
name: Option<Symbol>,
generic_params: &[hir::GenericParam<'_>],
- arg_names: &[Option<Ident>],
+ arg_idents: &[Option<Ident>],
) {
self.ibox(INDENT_UNIT);
self.print_formal_generic_params(generic_params);
@@ -2467,7 +2467,7 @@ fn print_ty_fn(
},
name,
generics,
- arg_names,
+ arg_idents,
None,
);
self.end();
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 872861d..9e1b70f 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -148,7 +148,7 @@
hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access
.help = specify the type explicitly
-hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
+hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
[true] {""}
*[other] {" "}in the current scope
}
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index b73cd26..dfaa374 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -727,7 +727,7 @@ pub(crate) struct NoAssociatedItem {
#[primary_span]
pub span: Span,
pub item_kind: &'static str,
- pub item_name: Ident,
+ pub item_ident: Ident,
pub ty_prefix: Cow<'static, str>,
pub ty_str: String,
pub trait_missing_method: bool,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3475d15..de2f039 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2920,8 +2920,13 @@ fn check_expr_field(
}
// We failed to check the expression, report an error.
- // Emits an error if we deref an infer variable, like calling `.field` on a base type of &_.
- self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
+ // Emits an error if we deref an infer variable, like calling `.field` on a base type
+ // of `&_`. We can also use this to suppress unnecessary "missing field" errors that
+ // will follow ambiguity errors.
+ let final_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
+ if let ty::Error(_) = final_ty.kind() {
+ return final_ty;
+ }
if let Some((adjustments, did)) = private_candidate {
// (#90483) apply adjustments to avoid ExprUseVisitor from
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index f4bd7ec..81eb851 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1136,7 +1136,7 @@ enum SuggestionText {
&& let self_implicit =
matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
&& let Some(Some(arg)) =
- self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit)
+ self.tcx.fn_arg_idents(fn_def_id).get(expected_idx.as_usize() + self_implicit)
&& arg.name != kw::SelfLower
{
format!("/* {} */", arg.name)
@@ -2619,7 +2619,7 @@ fn get_hir_param_info(
is_method: bool,
) -> Option<(IndexVec<ExpectedIdx, (Option<GenericIdx>, FnParam<'_>)>, &hir::Generics<'_>)>
{
- let (sig, generics, body_id, param_names) = match self.tcx.hir_get_if_local(def_id)? {
+ let (sig, generics, body_id, params) = match self.tcx.hir_get_if_local(def_id)? {
hir::Node::TraitItem(&hir::TraitItem {
generics,
kind: hir::TraitItemKind::Fn(sig, trait_fn),
@@ -2661,7 +2661,7 @@ fn get_hir_param_info(
None
}
});
- match (body_id, param_names) {
+ match (body_id, params) {
(Some(_), Some(_)) | (None, None) => unreachable!(),
(Some(body), None) => {
let params = self.tcx.hir_body(body).params;
@@ -2678,7 +2678,7 @@ fn get_hir_param_info(
params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
debug_assert_eq!(params.len(), fn_inputs.len());
Some((
- fn_inputs.zip(params.iter().map(|&ident| FnParam::Name(ident))).collect(),
+ fn_inputs.zip(params.iter().map(|&ident| FnParam::Ident(ident))).collect(),
generics,
))
}
@@ -2709,14 +2709,14 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
#[derive(Clone, Copy)]
enum FnParam<'hir> {
Param(&'hir hir::Param<'hir>),
- Name(Option<Ident>),
+ Ident(Option<Ident>),
}
impl FnParam<'_> {
fn span(&self) -> Span {
match self {
Self::Param(param) => param.span,
- Self::Name(ident) => {
+ Self::Ident(ident) => {
if let Some(ident) = ident {
ident.span
} else {
@@ -2738,7 +2738,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
{
Some(ident.name)
}
- FnParam::Name(ident)
+ FnParam::Ident(ident)
if let Some(ident) = ident
&& ident.name != kw::Underscore =>
{
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 4008021..ddfd27c 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -534,12 +534,12 @@ pub(crate) fn resolve_fully_qualified_call(
Ok((def_kind, pick.item.def_id))
}
- /// Finds item with name `item_name` defined in impl/trait `def_id`
+ /// Finds item with name `item_ident` defined in impl/trait `def_id`
/// and return it, or `None`, if no such item was defined there.
- fn associated_value(&self, def_id: DefId, item_name: Ident) -> Option<ty::AssocItem> {
+ fn associated_value(&self, def_id: DefId, item_ident: Ident) -> Option<ty::AssocItem> {
self.tcx
.associated_items(def_id)
- .find_by_name_and_namespace(self.tcx, item_name, Namespace::ValueNS, def_id)
+ .find_by_ident_and_namespace(self.tcx, item_ident, Namespace::ValueNS, def_id)
.copied()
}
}
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 246b23f..68f13d6 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -25,6 +25,7 @@
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
use rustc_middle::ty::print::{
PrintTraitRefExt as _, with_crate_prefix, with_forced_trimmed_paths,
+ with_no_visible_paths_if_doc_hidden,
};
use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;
@@ -584,7 +585,7 @@ fn report_no_match_method_error(
&self,
mut span: Span,
rcvr_ty: Ty<'tcx>,
- item_name: Ident,
+ item_ident: Ident,
expr_id: hir::HirId,
source: SelfSource<'tcx>,
args: Option<&'tcx [hir::Expr<'tcx>]>,
@@ -615,7 +616,7 @@ fn report_no_match_method_error(
} else if rcvr_ty.is_enum() {
"variant or associated item"
} else {
- match (item_name.as_str().chars().next(), rcvr_ty.is_fresh_ty()) {
+ match (item_ident.as_str().chars().next(), rcvr_ty.is_fresh_ty()) {
(Some(name), false) if name.is_lowercase() => "function or associated item",
(Some(_), false) => "associated item",
(Some(_), true) | (None, false) => "variant or associated item",
@@ -630,7 +631,7 @@ fn report_no_match_method_error(
rcvr_ty,
source,
span,
- item_name,
+ item_ident,
&short_ty_str,
&mut ty_file,
) {
@@ -642,13 +643,13 @@ fn report_no_match_method_error(
source,
span,
item_kind,
- item_name,
+ item_ident,
&short_ty_str,
&mut ty_file,
) {
return guar;
}
- span = item_name.span;
+ span = item_ident.span;
// Don't show generic arguments when the method can't be found in any implementation (#81576).
let mut ty_str_reported = ty_str.clone();
@@ -660,7 +661,7 @@ fn report_no_match_method_error(
self.tcx
.inherent_impls(adt_def.did())
.into_iter()
- .any(|def_id| self.associated_value(*def_id, item_name).is_some())
+ .any(|def_id| self.associated_value(*def_id, item_ident).is_some())
} else {
false
}
@@ -677,14 +678,14 @@ fn report_no_match_method_error(
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
tcx.is_diagnostic_item(sym::write_macro, def_id)
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
- }) && item_name.name == sym::write_fmt;
+ }) && item_ident.name == sym::write_fmt;
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
} else {
let mut err = self.dcx().create_err(NoAssociatedItem {
span,
item_kind,
- item_name,
+ item_ident,
ty_prefix: if trait_missing_method {
// FIXME(mu001999) E0599 maybe not suitable here because it is for types
Cow::from("trait")
@@ -698,7 +699,7 @@ fn report_no_match_method_error(
if is_method {
self.suggest_use_shadowed_binding_with_method(
source,
- item_name,
+ item_ident,
&ty_str_reported,
&mut err,
);
@@ -709,9 +710,9 @@ fn report_no_match_method_error(
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
&& let Res::SelfTyAlias { alias_to: impl_def_id, .. } = path.res
&& let DefKind::Impl { .. } = self.tcx.def_kind(impl_def_id)
- && let Some(candidate) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
+ && let Some(candidate) = tcx.associated_items(impl_def_id).find_by_ident_and_kind(
self.tcx,
- item_name,
+ item_ident,
ty::AssocKind::Type,
impl_def_id,
)
@@ -721,7 +722,7 @@ fn report_no_match_method_error(
{
let def_path = tcx.def_path_str(adt_def.did());
err.span_suggestion(
- ty.span.to(item_name.span),
+ ty.span.to(item_ident.span),
format!("to construct a value of type `{}`, use the explicit path", def_path),
def_path,
Applicability::MachineApplicable,
@@ -749,7 +750,7 @@ fn report_no_match_method_error(
self.find_builder_fn(&mut err, rcvr_ty, expr_id);
}
- if tcx.ty_is_opaque_future(rcvr_ty) && item_name.name == sym::poll {
+ if tcx.ty_is_opaque_future(rcvr_ty) && item_ident.name == sym::poll {
err.help(format!(
"method `poll` found on `Pin<&mut {ty_str}>`, \
see documentation for `std::pin::Pin`"
@@ -764,7 +765,7 @@ fn report_no_match_method_error(
{
self.suggest_await_before_method(
&mut err,
- item_name,
+ item_ident,
rcvr_ty,
cal,
span,
@@ -786,7 +787,7 @@ fn report_no_match_method_error(
if let SelfSource::MethodCall(rcvr_expr) = source
&& let ty::RawPtr(ty, ptr_mutbl) = *rcvr_ty.kind()
&& let Ok(pick) = self.lookup_probe_for_diagnostic(
- item_name,
+ item_ident,
Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl),
self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)),
ProbeScope::TraitsInScope,
@@ -807,7 +808,7 @@ fn report_no_match_method_error(
};
err.span_note(
tcx.def_span(pick.item.def_id),
- format!("the method `{item_name}` exists on the type `{ty}`", ty = pick.self_ty),
+ format!("the method `{item_ident}` exists on the type `{ty}`", ty = pick.self_ty),
);
let mut_str = ptr_mutbl.ptr_str();
err.note(format!(
@@ -833,7 +834,7 @@ fn report_no_match_method_error(
self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id));
let probe = self.lookup_probe_for_diagnostic(
- item_name,
+ item_ident,
output_ty,
call_expr,
ProbeScope::AllTraits,
@@ -872,13 +873,13 @@ fn report_no_match_method_error(
static_candidates,
rcvr_ty,
source,
- item_name,
+ item_ident,
args,
sugg_span,
);
self.note_candidates_on_method_error(
rcvr_ty,
- item_name,
+ item_ident,
source,
args,
span,
@@ -889,7 +890,7 @@ fn report_no_match_method_error(
} else if static_candidates.len() > 1 {
self.note_candidates_on_method_error(
rcvr_ty,
- item_name,
+ item_ident,
source,
args,
span,
@@ -903,7 +904,7 @@ fn report_no_match_method_error(
let mut restrict_type_params = false;
let mut suggested_derive = false;
let mut unsatisfied_bounds = false;
- if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
+ if item_ident.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
let msg = "consider using `len` instead";
if let SelfSource::MethodCall(_expr) = source {
err.span_suggestion_short(span, msg, "len", Applicability::MachineApplicable);
@@ -1348,7 +1349,7 @@ fn report_no_match_method_error(
};
let primary_message = primary_message.unwrap_or_else(|| {
format!(
- "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, \
+ "the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
but its trait bounds were not satisfied"
)
});
@@ -1378,7 +1379,7 @@ fn report_no_match_method_error(
// `Pin<&Self>`.
if targs.len() == 1 {
let mut item_segment = hir::PathSegment::invalid();
- item_segment.ident = item_name;
+ item_segment.ident = item_ident;
for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] {
let new_args =
tcx.mk_args_from_iter(targs.iter().map(|arg| match arg.as_type() {
@@ -1422,9 +1423,9 @@ fn report_no_match_method_error(
ty::Adt(adt, _) => self.tcx.is_lang_item(adt.did(), LangItem::String),
_ => false,
};
- if is_string_or_ref_str && item_name.name == sym::iter {
+ if is_string_or_ref_str && item_ident.name == sym::iter {
err.span_suggestion_verbose(
- item_name.span,
+ item_ident.span,
"because of the in-memory representation of `&str`, to obtain \
an `Iterator` over each of its codepoint use method `chars`",
"chars",
@@ -1438,7 +1439,7 @@ fn report_no_match_method_error(
.into_iter()
.copied()
.filter(|def_id| {
- if let Some(assoc) = self.associated_value(*def_id, item_name) {
+ if let Some(assoc) = self.associated_value(*def_id, item_ident) {
// Check for both mode is the same so we avoid suggesting
// incorrect associated item.
match (mode, assoc.fn_has_self_parameter, source) {
@@ -1499,7 +1500,7 @@ fn report_no_match_method_error(
// If the method name is the name of a field with a function or closure type,
// give a helping note that it has to be called as `(x.f)(...)`.
if let SelfSource::MethodCall(expr) = source {
- if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err)
+ if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_ident, &mut err)
&& similar_candidate.is_none()
&& !custom_span_label
{
@@ -1512,7 +1513,7 @@ fn report_no_match_method_error(
let confusable_suggested = self.confusable_method_name(
&mut err,
rcvr_ty,
- item_name,
+ item_ident,
args.map(|args| {
args.iter()
.map(|expr| {
@@ -1530,12 +1531,12 @@ fn report_no_match_method_error(
source,
span,
rcvr_ty,
- item_name,
+ item_ident,
expected.only_has_type(self),
);
}
- self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
+ self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_ident);
for (span, mut bounds) in bound_spans {
if !tcx.sess.source_map().is_span_accessible(span) {
@@ -1546,7 +1547,7 @@ fn report_no_match_method_error(
let pre = if Some(span) == ty_span {
ty_span.take();
format!(
- "{item_kind} `{item_name}` not found for this {} because it ",
+ "{item_kind} `{item_ident}` not found for this {} because it ",
rcvr_ty.prefix_string(self.tcx)
)
} else {
@@ -1566,7 +1567,7 @@ fn report_no_match_method_error(
err.span_label(
span,
format!(
- "{item_kind} `{item_name}` not found for this {}",
+ "{item_kind} `{item_ident}` not found for this {}",
rcvr_ty.prefix_string(self.tcx)
),
);
@@ -1578,7 +1579,7 @@ fn report_no_match_method_error(
&mut err,
span,
rcvr_ty,
- item_name,
+ item_ident,
args.map(|args| args.len() + 1),
source,
no_match_data.out_of_scope_traits.clone(),
@@ -1595,7 +1596,7 @@ fn report_no_match_method_error(
let adt_def = rcvr_ty.ty_adt_def().expect("enum is not an ADT");
if let Some(var_name) = edit_distance::find_best_match_for_name(
&adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
- item_name.name,
+ item_ident.name,
None,
) && let Some(variant) = adt_def.variants().iter().find(|s| s.name == var_name)
{
@@ -1736,14 +1737,14 @@ fn report_no_match_method_error(
if !find_candidate_for_method {
self.lookup_segments_chain_for_no_match_method(
&mut err,
- item_name,
+ item_ident,
item_kind,
source,
no_match_data,
);
}
- self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
+ self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_ident, expected);
err.emit()
}
@@ -3328,7 +3329,9 @@ fn suggest_use_candidates<F>(&self, candidates: Vec<DefId>, handle_candidates: F
let path_strings = candidates.iter().map(|trait_did| {
format!(
"{prefix}{}{postfix}\n",
- with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
+ with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
+ self.tcx.def_path_str(*trait_did)
+ )),
)
});
@@ -3336,7 +3339,9 @@ fn suggest_use_candidates<F>(&self, candidates: Vec<DefId>, handle_candidates: F
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"{prefix}{}::*{postfix} // trait {}\n",
- with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
+ with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
+ self.tcx.def_path_str(*parent_did)
+ )),
self.tcx.item_name(*trait_did),
)
});
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 8641348..fbc783c 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -163,9 +163,6 @@ fn demand_eqtype_pat(
enum AdjustMode {
/// Peel off all immediate reference types.
Peel,
- /// Reset binding mode to the initial mode.
- /// Used for destructuring assignment, where we don't want any match ergonomics.
- Reset,
/// Pass on the input binding mode and expected type.
Pass,
}
@@ -321,77 +318,14 @@ pub(crate) fn check_pat_top(
/// Conversely, inside this module, `check_pat_top` should never be used.
#[instrument(level = "debug", skip(self, pat_info))]
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx>) {
- let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info;
-
- let path_res = match pat.kind {
+ let opt_path_res = match pat.kind {
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, *hir_id, *span))
}
_ => None,
};
- let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
- let (expected, binding_mode, max_ref_mutbl) =
- self.calc_default_binding_mode(pat, expected, binding_mode, adjust_mode, max_ref_mutbl);
- let pat_info = PatInfo {
- binding_mode,
- max_ref_mutbl,
- top_info: ti,
- decl_origin: pat_info.decl_origin,
- current_depth: current_depth + 1,
- };
-
- let ty = match pat.kind {
- PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected,
- // We allow any type here; we ensure that the type is uninhabited during match checking.
- PatKind::Never => expected,
- PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
- let ty = self.check_pat_path(
- *hir_id,
- pat.hir_id,
- *span,
- qpath,
- path_res.unwrap(),
- expected,
- &pat_info.top_info,
- );
- self.write_ty(*hir_id, ty);
- ty
- }
- PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info),
- PatKind::Range(lhs, rhs, _) => {
- self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info)
- }
- PatKind::Binding(ba, var_id, ident, sub) => {
- self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
- }
- PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
- self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
- }
- PatKind::Struct(ref qpath, fields, has_rest_pat) => {
- self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
- }
- PatKind::Guard(pat, cond) => {
- self.check_pat(pat, expected, pat_info);
- self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
- expected
- }
- PatKind::Or(pats) => {
- for pat in pats {
- self.check_pat(pat, expected, pat_info);
- }
- expected
- }
- PatKind::Tuple(elements, ddpos) => {
- self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
- }
- PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
- PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
- PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
- PatKind::Slice(before, slice, after) => {
- self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
- }
- };
-
+ let adjust_mode = self.calc_adjust_mode(pat, opt_path_res.map(|(res, ..)| res));
+ let ty = self.check_pat_inner(pat, opt_path_res, adjust_mode, expected, pat_info);
self.write_ty(pat.hir_id, ty);
// (note_1): In most of the cases where (note_1) is referenced
@@ -437,27 +371,126 @@ fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<
// `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
}
- /// Compute the new expected type and default binding mode from the old ones
- /// as well as the pattern form we are currently checking.
- fn calc_default_binding_mode(
+ // Helper to avoid resolving the same path pattern several times.
+ fn check_pat_inner(
&self,
pat: &'tcx Pat<'tcx>,
- expected: Ty<'tcx>,
- def_br: ByRef,
+ opt_path_res: Option<(Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>])>,
adjust_mode: AdjustMode,
- max_ref_mutbl: MutblCap,
- ) -> (Ty<'tcx>, ByRef, MutblCap) {
+ expected: Ty<'tcx>,
+ pat_info: PatInfo<'tcx>,
+ ) -> Ty<'tcx> {
#[cfg(debug_assertions)]
- if def_br == ByRef::Yes(Mutability::Mut)
- && max_ref_mutbl != MutblCap::Mut
+ if pat_info.binding_mode == ByRef::Yes(Mutability::Mut)
+ && pat_info.max_ref_mutbl != MutblCap::Mut
&& self.downgrade_mut_inside_shared()
{
span_bug!(pat.span, "Pattern mutability cap violated!");
}
- match adjust_mode {
- AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
- AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
- AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
+
+ // Resolve type if needed.
+ let expected = if let AdjustMode::Peel = adjust_mode
+ && pat.default_binding_modes
+ {
+ self.try_structurally_resolve_type(pat.span, expected)
+ } else {
+ expected
+ };
+ let old_pat_info = pat_info;
+ let pat_info = PatInfo { current_depth: old_pat_info.current_depth + 1, ..old_pat_info };
+
+ match pat.kind {
+ // Peel off a `&` or `&mut` from the scrutinee type. See the examples in
+ // `tests/ui/rfcs/rfc-2005-default-binding-mode`.
+ _ if let AdjustMode::Peel = adjust_mode
+ && pat.default_binding_modes
+ && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() =>
+ {
+ debug!("inspecting {:?}", expected);
+
+ debug!("current discriminant is Ref, inserting implicit deref");
+ // Preserve the reference type. We'll need it later during THIR lowering.
+ self.typeck_results
+ .borrow_mut()
+ .pat_adjustments_mut()
+ .entry(pat.hir_id)
+ .or_default()
+ .push(expected);
+
+ let mut binding_mode = ByRef::Yes(match pat_info.binding_mode {
+ // If default binding mode is by value, make it `ref` or `ref mut`
+ // (depending on whether we observe `&` or `&mut`).
+ ByRef::No |
+ // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
+ ByRef::Yes(Mutability::Mut) => inner_mutability,
+ // Once a `ref`, always a `ref`.
+ // This is because a `& &mut` cannot mutate the underlying value.
+ ByRef::Yes(Mutability::Not) => Mutability::Not,
+ });
+
+ let mut max_ref_mutbl = pat_info.max_ref_mutbl;
+ if self.downgrade_mut_inside_shared() {
+ binding_mode = binding_mode.cap_ref_mutability(max_ref_mutbl.as_mutbl());
+ }
+ if binding_mode == ByRef::Yes(Mutability::Not) {
+ max_ref_mutbl = MutblCap::Not;
+ }
+ debug!("default binding mode is now {:?}", binding_mode);
+
+ // Use the old pat info to keep `current_depth` to its old value.
+ let new_pat_info = PatInfo { binding_mode, max_ref_mutbl, ..old_pat_info };
+ // Recurse with the new expected type.
+ self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info)
+ }
+ PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected,
+ // We allow any type here; we ensure that the type is uninhabited during match checking.
+ PatKind::Never => expected,
+ PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
+ let ty = self.check_pat_path(
+ *hir_id,
+ pat.hir_id,
+ *span,
+ qpath,
+ opt_path_res.unwrap(),
+ expected,
+ &pat_info.top_info,
+ );
+ self.write_ty(*hir_id, ty);
+ ty
+ }
+ PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info),
+ PatKind::Range(lhs, rhs, _) => {
+ self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info)
+ }
+ PatKind::Binding(ba, var_id, ident, sub) => {
+ self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
+ }
+ PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
+ self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
+ }
+ PatKind::Struct(ref qpath, fields, has_rest_pat) => {
+ self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
+ }
+ PatKind::Guard(pat, cond) => {
+ self.check_pat(pat, expected, pat_info);
+ self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
+ expected
+ }
+ PatKind::Or(pats) => {
+ for pat in pats {
+ self.check_pat(pat, expected, pat_info);
+ }
+ expected
+ }
+ PatKind::Tuple(elements, ddpos) => {
+ self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
+ }
+ PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
+ PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
+ PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
+ PatKind::Slice(before, slice, after) => {
+ self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
+ }
}
}
@@ -465,11 +498,6 @@ fn calc_default_binding_mode(
///
/// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> AdjustMode {
- // When we perform destructuring assignment, we disable default match bindings, which are
- // unintuitive in this context.
- if !pat.default_binding_modes {
- return AdjustMode::Reset;
- }
match &pat.kind {
// Type checking these product-like types successfully always require
// that the expected type be of those types and not reference types.
@@ -526,64 +554,6 @@ fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> A
}
}
- /// Peel off as many immediately nested `& mut?` from the expected type as possible
- /// and return the new expected type and binding default binding mode.
- /// The adjustments vector, if non-empty is stored in a table.
- fn peel_off_references(
- &self,
- pat: &'tcx Pat<'tcx>,
- expected: Ty<'tcx>,
- mut def_br: ByRef,
- mut max_ref_mutbl: MutblCap,
- ) -> (Ty<'tcx>, ByRef, MutblCap) {
- let mut expected = self.try_structurally_resolve_type(pat.span, expected);
- // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
- // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
- // the `Some(5)` which is not of type Ref.
- //
- // For each ampersand peeled off, update the binding mode and push the original
- // type into the adjustments vector.
- //
- // See the examples in `ui/match-defbm*.rs`.
- let mut pat_adjustments = vec![];
- while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
- debug!("inspecting {:?}", expected);
-
- debug!("current discriminant is Ref, inserting implicit deref");
- // Preserve the reference type. We'll need it later during THIR lowering.
- pat_adjustments.push(expected);
-
- expected = self.try_structurally_resolve_type(pat.span, inner_ty);
- def_br = ByRef::Yes(match def_br {
- // If default binding mode is by value, make it `ref` or `ref mut`
- // (depending on whether we observe `&` or `&mut`).
- ByRef::No |
- // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
- ByRef::Yes(Mutability::Mut) => inner_mutability,
- // Once a `ref`, always a `ref`.
- // This is because a `& &mut` cannot mutate the underlying value.
- ByRef::Yes(Mutability::Not) => Mutability::Not,
- });
- }
-
- if self.downgrade_mut_inside_shared() {
- def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
- }
- if def_br == ByRef::Yes(Mutability::Not) {
- max_ref_mutbl = MutblCap::Not;
- }
-
- if !pat_adjustments.is_empty() {
- debug!("default binding mode is now {:?}", def_br);
- self.typeck_results
- .borrow_mut()
- .pat_adjustments_mut()
- .insert(pat.hir_id, pat_adjustments);
- }
-
- (expected, def_br, max_ref_mutbl)
- }
-
fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
let ty = match <.kind {
rustc_hir::PatExprKind::Lit { lit, negated } => {
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index e367393..ff28dbe 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -5,7 +5,6 @@
[dependencies]
# tidy-alphabetical-start
-rustc-rayon = { version = "0.5.0" }
rustc-rayon-core = { version = "0.5.0" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 33b4a48..708fe23 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -348,6 +348,10 @@ pub struct Config {
/// the list of queries.
pub override_queries: Option<fn(&Session, &mut Providers)>,
+ /// An extra set of symbols to add to the symbol interner, the symbol indices
+ /// will start at [`PREDEFINED_SYMBOLS_COUNT`](rustc_span::symbol::PREDEFINED_SYMBOLS_COUNT)
+ pub extra_symbols: Vec<&'static str>,
+
/// This is a callback from the driver that is called to create a codegen backend.
///
/// Has no uses within this repository, but is used by bjorn3 for "the
@@ -409,6 +413,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
&early_dcx,
config.opts.edition,
config.opts.unstable_opts.threads,
+ &config.extra_symbols,
SourceMapInputs { file_loader, path_mapping, hash_kind, checksum_hash_kind },
|current_gcx| {
// The previous `early_dcx` can't be reused here because it doesn't
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7dfad16..fde1872 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -800,6 +800,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
sess.opts.cg.metadata.clone(),
sess.cfg_version,
);
+
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
let dep_type = DepsType { dep_names: rustc_query_impl::dep_kind_names() };
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index a8e5566..75a1b61 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -53,7 +53,7 @@ fn sess_and_cfg<F>(args: &[&'static str], f: F)
checksum_hash_kind,
});
- rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || {
+ rustc_span::create_session_globals_then(DEFAULT_EDITION, &[], sm_inputs, || {
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let io = CompilerIO {
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 83d8093..c3a939f 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -117,6 +117,7 @@ fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
thread_stack_size: usize,
edition: Edition,
sm_inputs: SourceMapInputs,
+ extra_symbols: &[&'static str],
f: F,
) -> R {
// The "thread pool" is a single spawned thread in the non-parallel
@@ -134,9 +135,12 @@ fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
// name contains null bytes.
let r = builder
.spawn_scoped(s, move || {
- rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
- f(CurrentGcx::new())
- })
+ rustc_span::create_session_globals_then(
+ edition,
+ extra_symbols,
+ Some(sm_inputs),
+ || f(CurrentGcx::new()),
+ )
})
.unwrap()
.join();
@@ -152,6 +156,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
thread_builder_diag: &EarlyDiagCtxt,
edition: Edition,
threads: usize,
+ extra_symbols: &[&'static str],
sm_inputs: SourceMapInputs,
f: F,
) -> R {
@@ -168,18 +173,24 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
if !sync::is_dyn_thread_safe() {
- return run_in_thread_with_globals(thread_stack_size, edition, sm_inputs, |current_gcx| {
- // Register the thread for use with the `WorkerLocal` type.
- registry.register();
+ return run_in_thread_with_globals(
+ thread_stack_size,
+ edition,
+ sm_inputs,
+ extra_symbols,
+ |current_gcx| {
+ // Register the thread for use with the `WorkerLocal` type.
+ registry.register();
- f(current_gcx)
- });
+ f(current_gcx)
+ },
+ );
}
let current_gcx = FromDyn::from(CurrentGcx::new());
let current_gcx2 = current_gcx.clone();
- let builder = rayon::ThreadPoolBuilder::new()
+ let builder = rayon_core::ThreadPoolBuilder::new()
.thread_name(|_| "rustc".to_string())
.acquire_thread_handler(jobserver::acquire_thread)
.release_thread_handler(jobserver::release_thread)
@@ -230,13 +241,13 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
// pool. Upon creation, each worker thread created gets a copy of the
// session globals in TLS. This is possible because `SessionGlobals` impls
// `Send` in the parallel compiler.
- rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
+ rustc_span::create_session_globals_then(edition, extra_symbols, Some(sm_inputs), || {
rustc_span::with_session_globals(|session_globals| {
let session_globals = FromDyn::from(session_globals);
builder
.build_scoped(
// Initialize each new worker thread when created.
- move |thread: rayon::ThreadBuilder| {
+ move |thread: rayon_core::ThreadBuilder| {
// Register the thread for use with the `WorkerLocal` type.
registry.register();
@@ -245,7 +256,9 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
})
},
// Run `f` on the first thread in the thread pool.
- move |pool: &rayon::ThreadPool| pool.install(|| f(current_gcx.into_inner())),
+ move |pool: &rayon_core::ThreadPool| {
+ pool.install(|| f(current_gcx.into_inner()))
+ },
)
.unwrap()
})
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 885a730..16c9e08 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -859,7 +859,7 @@ pub fn get_associated_type(
) -> Option<Ty<'tcx>> {
let tcx = self.tcx;
tcx.associated_items(trait_id)
- .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
+ .find_by_ident_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
.and_then(|assoc| {
let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]);
tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok()
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index df567e8..a3e7c84 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -423,11 +423,11 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
}
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &hir::TraitItem<'_>) {
- if let hir::TraitItemKind::Fn(_, hir::TraitFn::Required(pnames)) = item.kind {
+ if let hir::TraitItemKind::Fn(_, hir::TraitFn::Required(param_idents)) = item.kind {
self.check_snake_case(cx, "trait method", &item.ident);
- for param_name in pnames {
- if let Some(param_name) = param_name {
- self.check_snake_case(cx, "variable", param_name);
+ for param_ident in param_idents {
+ if let Some(param_ident) = param_ident {
+ self.check_snake_case(cx, "variable", param_ident);
}
}
}
diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index 37200f6..0400de6 100644
--- a/compiler/rustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
@@ -142,13 +142,13 @@ pub(super) fn symbols(input: TokenStream) -> TokenStream {
output
}
-struct Preinterned {
+struct Predefined {
idx: u32,
span_of_name: Span,
}
struct Entries {
- map: HashMap<String, Preinterned>,
+ map: HashMap<String, Predefined>,
}
impl Entries {
@@ -163,7 +163,7 @@ fn insert(&mut self, span: Span, s: &str, errors: &mut Errors) -> u32 {
prev.idx
} else {
let idx = self.len();
- self.map.insert(s.to_string(), Preinterned { idx, span_of_name: span });
+ self.map.insert(s.to_string(), Predefined { idx, span_of_name: span });
idx
}
}
@@ -295,10 +295,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
}
let symbol_digits_base = entries.map["0"].idx;
- let preinterned_symbols_count = entries.len();
+ let predefined_symbols_count = entries.len();
let output = quote! {
const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base;
- const PREINTERNED_SYMBOLS_COUNT: u32 = #preinterned_symbols_count;
+
+ /// The number of predefined symbols; this is the the first index for
+ /// extra pre-interned symbols in an Interner created via
+ /// [`Interner::with_extra_symbols`].
+ pub const PREDEFINED_SYMBOLS_COUNT: u32 = #predefined_symbols_count;
#[doc(hidden)]
#[allow(non_upper_case_globals)]
@@ -315,10 +319,13 @@ pub mod sym_generated {
}
impl Interner {
- pub(crate) fn fresh() -> Self {
- Interner::prefill(&[
- #prefill_stream
- ])
+ /// Creates an `Interner` with the predefined symbols from the `symbols!` macro and
+ /// any extra symbols provided by external drivers such as Clippy
+ pub(crate) fn with_extra_symbols(extra_symbols: &[&'static str]) -> Self {
+ Interner::prefill(
+ &[#prefill_stream],
+ extra_symbols,
+ )
}
}
};
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 4610a57..4cc12ca 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -562,9 +562,9 @@ fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(s)
})
}
- SYMBOL_PREINTERNED => {
+ SYMBOL_PREDEFINED => {
let symbol_index = self.read_u32();
- Symbol::new_from_decoded(symbol_index)
+ Symbol::new(symbol_index)
}
_ => unreachable!(),
}
@@ -1313,7 +1313,7 @@ fn is_item_mir_available(self, id: DefIndex) -> bool {
fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {
self.root
.tables
- .fn_arg_names
+ .fn_arg_idents
.get(self, id)
.expect("argument names not encoded for a function")
.decode((self, sess))
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 3dc82ce..ecc2dcc 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -286,7 +286,7 @@ fn into_args(self) -> (DefId, SimplifiedType) {
rendered_const => { table }
rendered_precise_capturing_args => { table }
asyncness => { table_direct }
- fn_arg_names => { table }
+ fn_arg_idents => { table }
coroutine_kind => { table_direct }
coroutine_for_closure => { table }
coroutine_by_move_body_def_id => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 55bb984..5c8e288 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -201,9 +201,9 @@ fn encode_span(&mut self, span: Span) {
}
fn encode_symbol(&mut self, symbol: Symbol) {
- // if symbol preinterned, emit tag and symbol index
- if symbol.is_preinterned() {
- self.opaque.emit_u8(SYMBOL_PREINTERNED);
+ // if symbol predefined, emit tag and symbol index
+ if symbol.is_predefined() {
+ self.opaque.emit_u8(SYMBOL_PREDEFINED);
self.opaque.emit_u32(symbol.as_u32());
} else {
// otherwise write it as string or as offset to it
@@ -1469,7 +1469,7 @@ fn encode_def_ids(&mut self) {
}
if let DefKind::Fn | DefKind::AssocFn = def_kind {
self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
- record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
+ record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id));
}
if let Some(name) = tcx.intrinsic(def_id) {
record!(self.tables.intrinsic[def_id] <- name);
@@ -2199,7 +2199,7 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
}
let reachable_set = tcx.reachable_set(());
- par_for_each_in(tcx.mir_keys(()), |&def_id| {
+ par_for_each_in(tcx.mir_keys(()), |&&def_id| {
let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id);
if encode_const {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 96a1f65..2f27e5f 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -451,7 +451,7 @@ fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
rendered_const: Table<DefIndex, LazyValue<String>>,
rendered_precise_capturing_args: Table<DefIndex, LazyArray<PreciseCapturingArgKind<Symbol, Symbol>>>,
asyncness: Table<DefIndex, ty::Asyncness>,
- fn_arg_names: Table<DefIndex, LazyArray<Option<Ident>>>,
+ fn_arg_idents: Table<DefIndex, LazyArray<Option<Ident>>>,
coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
coroutine_for_closure: Table<DefIndex, RawDefId>,
adt_destructor: Table<DefIndex, LazyValue<ty::Destructor>>,
@@ -586,7 +586,7 @@ fn length(self) -> Option<rustc_span::BytePos> {
// Tags for encoding Symbol's
const SYMBOL_STR: u8 = 0;
const SYMBOL_OFFSET: u8 = 1;
-const SYMBOL_PREINTERNED: u8 = 2;
+const SYMBOL_PREDEFINED: u8 = 2;
pub fn provide(providers: &mut Providers) {
encoder::provide(providers);
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 21ab06c..daf9542 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -281,7 +281,7 @@ pub fn hir_body_owned_by(self, id: LocalDefId) -> &'tcx Body<'tcx> {
})
}
- pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Option<Ident>> {
+ pub fn hir_body_param_idents(self, id: BodyId) -> impl Iterator<Item = Option<Ident>> {
self.hir_body(id).params.iter().map(|param| match param.pat.kind {
PatKind::Binding(_, _, ident, _) => Some(ident),
PatKind::Wild => Some(Ident::new(kw::Underscore, param.pat.span)),
@@ -343,7 +343,7 @@ pub fn hir_body_owners(self) -> impl Iterator<Item = LocalDefId> {
#[inline]
pub fn par_hir_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
- par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
+ par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&&def_id| f(def_id));
}
pub fn hir_ty_param_owner(self, def_id: LocalDefId) -> LocalDefId {
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 74369b6..640ac70 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -83,35 +83,35 @@ pub fn par_items(
&self,
f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
- try_par_for_each_in(&self.free_items[..], |&id| f(id))
+ try_par_for_each_in(&self.free_items[..], |&&id| f(id))
}
pub fn par_trait_items(
&self,
f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
- try_par_for_each_in(&self.trait_items[..], |&id| f(id))
+ try_par_for_each_in(&self.trait_items[..], |&&id| f(id))
}
pub fn par_impl_items(
&self,
f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
- try_par_for_each_in(&self.impl_items[..], |&id| f(id))
+ try_par_for_each_in(&self.impl_items[..], |&&id| f(id))
}
pub fn par_foreign_items(
&self,
f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
- try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
+ try_par_for_each_in(&self.foreign_items[..], |&&id| f(id))
}
pub fn par_opaques(
&self,
f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
- try_par_for_each_in(&self.opaques[..], |&id| f(id))
+ try_par_for_each_in(&self.opaques[..], |&&id| f(id))
}
}
@@ -215,9 +215,9 @@ pub fn provide(providers: &mut Providers) {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
tcx.hir_opt_ident_span(hir_id)
};
- providers.fn_arg_names = |tcx, def_id| {
+ providers.fn_arg_idents = |tcx, def_id| {
if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() {
- tcx.arena.alloc_from_iter(tcx.hir_body_param_names(body_id))
+ tcx.arena.alloc_from_iter(tcx.hir_body_param_idents(body_id))
} else if let Node::TraitItem(&TraitItem {
kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
..
@@ -231,7 +231,7 @@ pub fn provide(providers: &mut Providers) {
} else {
span_bug!(
tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
- "fn_arg_names: unexpected item {:?}",
+ "fn_arg_idents: unexpected item {:?}",
def_id
);
}
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 707c8d04..ff9d32e 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -652,6 +652,8 @@ pub enum CallSource {
/// Other types of desugaring that did not come from the HIR, but we don't care about
/// for diagnostics (yet).
Misc,
+ /// Use of value, generating a clone function call
+ Use,
/// Normal function call, no special source
Normal,
}
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index b2c51ad..82e8422 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -454,7 +454,7 @@ impl SwitchTargets {
/// Like [`SwitchTargets::target_for_value`], but returning the same type as
/// [`Terminator::successors`].
#[inline]
- #[cfg_attr(not(bootstrap), define_opaque(Successors))]
+ #[define_opaque(Successors)]
pub fn successors_for_value(&self, value: u128) -> Successors<'_> {
let target = self.target_for_value(value);
(&[]).into_iter().copied().chain(Some(target))
@@ -463,7 +463,7 @@ pub fn successors_for_value(&self, value: u128) -> Successors<'_> {
impl<'tcx> TerminatorKind<'tcx> {
#[inline]
- #[cfg_attr(not(bootstrap), define_opaque(Successors))]
+ #[define_opaque(Successors)]
pub fn successors(&self) -> Successors<'_> {
use self::TerminatorKind::*;
match *self {
@@ -502,7 +502,7 @@ pub fn successors(&self) -> Successors<'_> {
}
#[inline]
- #[cfg_attr(not(bootstrap), define_opaque(SuccessorsMut))]
+ #[define_opaque(SuccessorsMut)]
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
use self::TerminatorKind::*;
match *self {
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 6c6b9a5..5bd111f 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -25,7 +25,7 @@ pub trait EraseType: Copy {
pub type Erase<T: EraseType> = Erased<impl Copy>;
#[inline(always)]
-#[cfg_attr(not(bootstrap), define_opaque(Erase))]
+#[define_opaque(Erase)]
pub fn erase<T: EraseType>(src: T) -> Erase<T> {
// Ensure the sizes match
const {
@@ -49,7 +49,7 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
/// Restores an erased value.
#[inline(always)]
-#[cfg_attr(not(bootstrap), define_opaque(Erase))]
+#[define_opaque(Erase)]
pub fn restore<T: EraseType>(value: Erase<T>) -> T {
let value: Erased<<T as EraseType>::Result> = value;
// See comment in `erase` for why we use `transmute_unchecked`.
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index a1df27a..28a59d3 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1026,6 +1026,13 @@
separate_provide_extern
}
+ /// Given an `impl_def_id`, return true if the self type is guaranteed to be unsized due
+ /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct
+ /// whose tail is one of those types.
+ query impl_self_is_guaranteed_unsized(impl_def_id: DefId) -> bool {
+ desc { |tcx| "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) }
+ }
+
/// Maps a `DefId` of a type to a list of its inherent impls.
/// Contains implementations of methods that are inherent to a type.
/// Methods in these implementations don't need to be exported.
@@ -1435,8 +1442,8 @@
desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
}
- query fn_arg_names(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] {
- desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
+ query fn_arg_idents(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] {
+ desc { |tcx| "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
@@ -1893,6 +1900,11 @@
// The macro which defines `rustc_metadata::provide_extern` depends on this query's name.
// Changing the name should cause a compiler error, but in case that changes, be aware.
+ //
+ // The hash should not be calculated before the `analysis` pass is complete, specifically
+ // until `tcx.untracked().definitions.freeze()` has been called, otherwise if incremental
+ // compilation is enabled calculating this hash can freeze this structure too early in
+ // compilation and cause subsequent crashes when attempting to write to `definitions`
query crate_hash(_: CrateNum) -> Svh {
eval_always
desc { "looking up the hash a crate" }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index c6ecc67..f78398c 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -46,7 +46,7 @@
// Tags for encoding Symbol's
const SYMBOL_STR: u8 = 0;
const SYMBOL_OFFSET: u8 = 1;
-const SYMBOL_PREINTERNED: u8 = 2;
+const SYMBOL_PREDEFINED: u8 = 2;
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
@@ -674,9 +674,9 @@ fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(s)
})
}
- SYMBOL_PREINTERNED => {
+ SYMBOL_PREDEFINED => {
let symbol_index = self.read_u32();
- Symbol::new_from_decoded(symbol_index)
+ Symbol::new(symbol_index)
}
_ => unreachable!(),
}
@@ -892,9 +892,9 @@ fn encode_span(&mut self, span: Span) {
// copy&paste impl from rustc_metadata
fn encode_symbol(&mut self, symbol: Symbol) {
- // if symbol preinterned, emit tag and symbol index
- if symbol.is_preinterned() {
- self.encoder.emit_u8(SYMBOL_PREINTERNED);
+ // if symbol predefined, emit tag and symbol index
+ if symbol.is_predefined() {
+ self.encoder.emit_u8(SYMBOL_PREDEFINED);
self.encoder.emit_u32(symbol.as_u32());
} else {
// otherwise write it as string or as offset to it
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index ce4c08a..bbaf735 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -98,10 +98,10 @@ pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
pub fn descr(&self) -> &'static str {
match self.kind {
- ty::AssocKind::Const => "const",
+ ty::AssocKind::Const => "associated const",
ty::AssocKind::Fn if self.fn_has_self_parameter => "method",
ty::AssocKind::Fn => "associated function",
- ty::AssocKind::Type => "type",
+ ty::AssocKind::Type => "associated type",
}
}
@@ -155,6 +155,8 @@ pub fn as_def_kind(&self) -> DefKind {
impl std::fmt::Display for AssocKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
+ // FIXME: fails to distinguish between "associated function" and
+ // "method" because `has_self` isn't known here.
AssocKind::Fn => write!(f, "method"),
AssocKind::Const => write!(f, "associated const"),
AssocKind::Type => write!(f, "associated type"),
@@ -199,8 +201,9 @@ pub fn filter_by_name_unhygienic(
self.items.get_by_key(name)
}
- /// Returns the associated item with the given name and `AssocKind`, if one exists.
- pub fn find_by_name_and_kind(
+ /// Returns the associated item with the given identifier and `AssocKind`, if one exists.
+ /// The identifier is matched hygienically.
+ pub fn find_by_ident_and_kind(
&self,
tcx: TyCtxt<'_>,
ident: Ident,
@@ -212,8 +215,9 @@ pub fn find_by_name_and_kind(
.find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
}
- /// Returns the associated item with the given name and any of `AssocKind`, if one exists.
- pub fn find_by_name_and_kinds(
+ /// Returns the associated item with the given identifier and any of `AssocKind`, if one
+ /// exists. The identifier is matched hygienically.
+ pub fn find_by_ident_and_kinds(
&self,
tcx: TyCtxt<'_>,
ident: Ident,
@@ -221,11 +225,12 @@ pub fn find_by_name_and_kinds(
kinds: &[AssocKind],
parent_def_id: DefId,
) -> Option<&ty::AssocItem> {
- kinds.iter().find_map(|kind| self.find_by_name_and_kind(tcx, ident, *kind, parent_def_id))
+ kinds.iter().find_map(|kind| self.find_by_ident_and_kind(tcx, ident, *kind, parent_def_id))
}
- /// Returns the associated item with the given name in the given `Namespace`, if one exists.
- pub fn find_by_name_and_namespace(
+ /// Returns the associated item with the given identifier in the given `Namespace`, if one
+ /// exists. The identifier is matched hygienically.
+ pub fn find_by_ident_and_namespace(
&self,
tcx: TyCtxt<'_>,
ident: Ident,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 162ca1f..abf6cbb 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -437,6 +437,10 @@ fn explicit_implied_const_bounds(
)
}
+ fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
+ self.impl_self_is_guaranteed_unsized(impl_def_id)
+ }
+
fn has_target_features(self, def_id: DefId) -> bool {
!self.codegen_fn_attrs(def_id).target_features.is_empty()
}
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index a0e67929..5ecf117 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -279,7 +279,7 @@ pub fn short_string<T>(self, p: T, path: &mut Option<PathBuf>) -> String
p.hash(&mut s);
let hash = s.finish();
*path = Some(path.take().unwrap_or_else(|| {
- self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
+ self.output_filenames(()).temp_path_for_diagnostic(&format!("long-type-{hash}.txt"))
}));
let Ok(mut file) =
File::options().create(true).read(true).append(true).open(&path.as_ref().unwrap())
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 80f1bd7..a2b3aca 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1939,15 +1939,15 @@ pub fn span_of_impl(self, impl_def_id: DefId) -> Result<Span, Symbol> {
/// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
/// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
/// definition's parent/scope to perform comparison.
- pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
- // We could use `Ident::eq` here, but we deliberately don't. The name
+ pub fn hygienic_eq(self, use_ident: Ident, def_ident: Ident, def_parent_def_id: DefId) -> bool {
+ // We could use `Ident::eq` here, but we deliberately don't. The identifier
// comparison fails frequently, and we want to avoid the expensive
// `normalize_to_macros_2_0()` calls required for the span comparison whenever possible.
- use_name.name == def_name.name
- && use_name
+ use_ident.name == def_ident.name
+ && use_ident
.span
.ctxt()
- .hygienic_eq(def_name.span.ctxt(), self.expn_that_defined(def_parent_def_id))
+ .hygienic_eq(def_ident.span.ctxt(), self.expn_that_defined(def_parent_def_id))
}
pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 5904dea..9172c5d 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -382,7 +382,7 @@ pub fn shrunk_instance_name<'tcx>(
return (s, None);
}
- let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
+ let path = tcx.output_filenames(()).temp_path_for_diagnostic("long-type.txt");
let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
(shrunk, written_to_path)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 0765d06..667cc5c 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -63,6 +63,7 @@ macro_rules! scoped_cx {
static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
static REDUCED_QUERIES: Cell<bool> = const { Cell::new(false) };
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
+ static NO_VISIBLE_PATH_IF_DOC_HIDDEN: Cell<bool> = const { Cell::new(false) };
static RTN_MODE: Cell<RtnMode> = const { Cell::new(RtnMode::ForDiagnostic) };
}
@@ -134,6 +135,8 @@ pub fn $name() -> bool {
/// Prevent selection of visible paths. `Display` impl of DefId will prefer
/// visible (public) reexports of types as paths.
fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
+ /// Prevent selection of visible paths if the paths are through a doc hidden path.
+ fn with_no_visible_paths_if_doc_hidden(NoVisibleIfDocHiddenGuard, NO_VISIBLE_PATH_IF_DOC_HIDDEN);
);
#[must_use]
@@ -569,6 +572,10 @@ fn try_print_visible_def_path_recur(
return Ok(false);
};
+ if self.tcx().is_doc_hidden(visible_parent) && with_no_visible_paths_if_doc_hidden() {
+ return Ok(false);
+ }
+
let actual_parent = self.tcx().opt_parent(def_id);
debug!(
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs
index 333e694..a9a0799 100644
--- a/compiler/rustc_mir_build/src/builder/expr/into.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/into.rs
@@ -328,7 +328,7 @@ pub(crate) fn expr_into_dest(
destination,
target: Some(success),
unwind: UnwindAction::Unreachable,
- call_source: CallSource::Misc,
+ call_source: CallSource::Use,
fn_span: expr_span,
},
);
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 6e676ac..1dbb35f 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1689,7 +1689,7 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
let mut recursion_depths = DefIdMap::default();
collect_items_rec(
tcx,
- dummy_spanned(root),
+ dummy_spanned(*root),
&state,
&mut recursion_depths,
recursion_limit,
diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
index 838bfda..55d52d5 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
@@ -148,11 +148,7 @@ fn lint_large_assignment(
span: Span,
) {
let source_info = self.body.source_info(location);
- for reported_span in &self.move_size_spans {
- if reported_span.overlaps(span) {
- return;
- }
- }
+
let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
let Some(lint_root) = lint_root else {
// This happens when the issue is in a function from a foreign crate that
@@ -162,19 +158,40 @@ fn lint_large_assignment(
// but correct span? This would make the lint at least accept crate-level lint attributes.
return;
};
+
+ // If the source scope is inlined by the MIR inliner, report the lint on the call site.
+ let reported_span = self
+ .body
+ .source_scopes
+ .get(source_info.scope)
+ .and_then(|source_scope_data| source_scope_data.inlined)
+ .map(|(_, call_site)| call_site)
+ .unwrap_or(span);
+
+ for previously_reported_span in &self.move_size_spans {
+ if previously_reported_span.overlaps(reported_span) {
+ return;
+ }
+ }
+
self.tcx.emit_node_span_lint(
LARGE_ASSIGNMENTS,
lint_root,
- span,
- LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 },
+ reported_span,
+ LargeAssignmentsLint {
+ span: reported_span,
+ size: too_large_size.bytes(),
+ limit: limit as u64,
+ },
);
- self.move_size_spans.push(span);
+
+ self.move_size_spans.push(reported_span);
}
}
fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> {
for impl_def_id in tcx.inherent_impls(def_id) {
- if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
+ if let Some(new) = tcx.associated_items(impl_def_id).find_by_ident_and_kind(
tcx,
fn_ident,
AssocKind::Fn,
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index f575fe0..92cdc28 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -6,7 +6,7 @@
// tidy-alphabetical-start
#![allow(rustc::usage_of_type_ir_inherent)]
-#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_traits))]
+#![allow(rustc::usage_of_type_ir_traits)]
// tidy-alphabetical-end
pub mod canonicalizer;
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index de6d21d..2d027f1 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -134,7 +134,7 @@ fn probe_and_match_goal_against_assumption(
// Add GAT where clauses from the trait's definition
// FIXME: We don't need these, since these are the type's own WF obligations.
ecx.add_goals(
- GoalSource::Misc,
+ GoalSource::AliasWellFormed,
cx.own_predicates_of(goal.predicate.def_id())
.iter_instantiated(cx, goal.predicate.alias.args)
.map(|pred| goal.with(cx, pred)),
@@ -199,7 +199,7 @@ fn consider_impl_candidate(
// Add GAT where clauses from the trait's definition.
// FIXME: We don't need these, since these are the type's own WF obligations.
ecx.add_goals(
- GoalSource::Misc,
+ GoalSource::AliasWellFormed,
cx.own_predicates_of(goal.predicate.def_id())
.iter_instantiated(cx, goal.predicate.alias.args)
.map(|pred| goal.with(cx, pred)),
@@ -232,7 +232,33 @@ fn consider_impl_candidate(
};
if !cx.has_item_definition(target_item_def_id) {
- return error_response(ecx, cx.delay_bug("missing item"));
+ // If the impl is missing an item, it's either because the user forgot to
+ // provide it, or the user is not *obligated* to provide it (because it
+ // has a trivially false `Sized` predicate). If it's the latter, we cannot
+ // delay a bug because we can have trivially false where clauses, so we
+ // treat it as rigid.
+ if cx.impl_self_is_guaranteed_unsized(impl_def_id) {
+ match ecx.typing_mode() {
+ ty::TypingMode::Coherence => {
+ return ecx.evaluate_added_goals_and_make_canonical_response(
+ Certainty::AMBIGUOUS,
+ );
+ }
+ ty::TypingMode::Analysis { .. }
+ | ty::TypingMode::Borrowck { .. }
+ | ty::TypingMode::PostBorrowckAnalysis { .. }
+ | ty::TypingMode::PostAnalysis => {
+ ecx.structurally_instantiate_normalizes_to_term(
+ goal,
+ goal.predicate.alias,
+ );
+ return ecx
+ .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+ }
+ }
+ } else {
+ return error_response(ecx, cx.delay_bug("missing item"));
+ }
}
let target_container_def_id = cx.parent(target_item_def_id);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 3647bf2..0650181 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -602,21 +602,13 @@ fn parse_item_impl(
let polarity = self.parse_polarity();
// Parse both types and traits as a type, then reinterpret if necessary.
- let err_path = |span| ast::Path::from_ident(Ident::new(kw::Empty, span));
let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
{
let span = self.prev_token.span.between(self.token.span);
- self.dcx().emit_err(errors::MissingTraitInTraitImpl {
+ return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
span,
for_span: span.to(self.token.span),
- });
-
- P(Ty {
- kind: TyKind::Path(None, err_path(span)),
- span,
- id: DUMMY_NODE_ID,
- tokens: None,
- })
+ }));
} else {
self.parse_ty_with_generics_recovery(&generics)?
};
@@ -657,6 +649,7 @@ fn parse_item_impl(
other => {
if let TyKind::ImplTrait(_, bounds) = other
&& let [bound] = bounds.as_slice()
+ && let GenericBound::Trait(poly_trait_ref) = bound
{
// Suggest removing extra `impl` keyword:
// `impl<T: Default> impl Default for Wrapper<T>`
@@ -666,12 +659,12 @@ fn parse_item_impl(
extra_impl_kw,
impl_trait_span: ty_first.span,
});
+ poly_trait_ref.trait_ref.path.clone()
} else {
- self.dcx().emit_err(errors::ExpectedTraitInTraitImplFoundType {
- span: ty_first.span,
- });
+ return Err(self.dcx().create_err(
+ errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
+ ));
}
- err_path(ty_first.span)
}
};
let trait_ref = TraitRef { path, ref_id: ty_first.id };
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 9f34417..56fd3a6 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -141,7 +141,7 @@ pub fn new(
let colors = DepNodeColorMap::new(prev_graph_node_count);
// Instantiate a node with zero dependencies only once for anonymous queries.
- let _green_node_index = current.alloc_node(
+ let _green_node_index = current.alloc_new_node(
DepNode { kind: D::DEP_KIND_ANON_ZERO_DEPS, hash: current.anon_id_seed.into() },
EdgesVec::new(),
Fingerprint::ZERO,
@@ -149,7 +149,7 @@ pub fn new(
assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE);
// Instantiate a dependy-less red node only once for anonymous queries.
- let red_node_index = current.alloc_node(
+ let red_node_index = current.alloc_new_node(
DepNode { kind: D::DEP_KIND_RED, hash: Fingerprint::ZERO.into() },
EdgesVec::new(),
Fingerprint::ZERO,
@@ -438,7 +438,7 @@ pub(crate) fn with_anon_task_inner<Tcx: DepContext<Deps = D>, OP, R>(
// memory impact of this `anon_node_to_index` map remains tolerable, and helps
// us avoid useless growth of the graph with almost-equivalent nodes.
self.current.anon_node_to_index.get_or_insert_with(target_dep_node, || {
- self.current.alloc_node(target_dep_node, task_deps, Fingerprint::ZERO)
+ self.current.alloc_new_node(target_dep_node, task_deps, Fingerprint::ZERO)
})
}
};
@@ -680,8 +680,8 @@ fn encode_diagnostic<Qcx: QueryContext>(
qcx: Qcx,
diagnostic: &DiagInner,
) -> DepNodeIndex {
- // Use `send` so we get an unique index, even though the dep node is not.
- let dep_node_index = self.current.encoder.send(
+ // Use `send_new` so we get an unique index, even though the dep node is not.
+ let dep_node_index = self.current.encoder.send_new(
DepNode {
kind: D::DEP_KIND_SIDE_EFFECT,
hash: PackedFingerprint::from(Fingerprint::ZERO),
@@ -713,20 +713,22 @@ fn force_diagnostic_node<Qcx: QueryContext>(
}
}
- // Manually recreate the node as `promote_node_and_deps_to_current` expects all
- // green dependencies.
- let dep_node_index = self.current.encoder.send(
+ // Use `send_and_color` as `promote_node_and_deps_to_current` expects all
+ // green dependencies. `send_and_color` will also prevent multiple nodes
+ // being encoded for concurrent calls.
+ let dep_node_index = self.current.encoder.send_and_color(
+ prev_index,
+ &self.colors,
DepNode {
kind: D::DEP_KIND_SIDE_EFFECT,
hash: PackedFingerprint::from(Fingerprint::ZERO),
},
Fingerprint::ZERO,
std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
+ true,
);
+ // This will just overwrite the same value for concurrent calls.
qcx.store_side_effect(dep_node_index, side_effect);
-
- // Mark the node as green.
- self.colors.insert(prev_index, DepNodeColor::Green(dep_node_index));
})
}
@@ -736,38 +738,43 @@ fn alloc_and_color_node(
edges: EdgesVec,
fingerprint: Option<Fingerprint>,
) -> DepNodeIndex {
- let dep_node_index =
- self.current.alloc_node(key, edges, fingerprint.unwrap_or(Fingerprint::ZERO));
-
if let Some(prev_index) = self.previous.node_to_index_opt(&key) {
// Determine the color and index of the new `DepNode`.
- let color = if let Some(fingerprint) = fingerprint {
+ let is_green = if let Some(fingerprint) = fingerprint {
if fingerprint == self.previous.fingerprint_by_index(prev_index) {
// This is a green node: it existed in the previous compilation,
// its query was re-executed, and it has the same result as before.
- DepNodeColor::Green(dep_node_index)
+ true
} else {
// This is a red node: it existed in the previous compilation, its query
// was re-executed, but it has a different result from before.
- DepNodeColor::Red
+ false
}
} else {
// This is a red node, effectively: it existed in the previous compilation
// session, its query was re-executed, but it doesn't compute a result hash
// (i.e. it represents a `no_hash` query), so we have no way of determining
// whether or not the result was the same as before.
- DepNodeColor::Red
+ false
};
- debug_assert!(
- self.colors.get(prev_index).is_none(),
- "DepGraph::with_task() - Duplicate DepNodeColor insertion for {key:?}",
+ let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO);
+
+ let dep_node_index = self.current.encoder.send_and_color(
+ prev_index,
+ &self.colors,
+ key,
+ fingerprint,
+ edges,
+ is_green,
);
- self.colors.insert(prev_index, color);
- }
+ self.current.record_node(dep_node_index, key, fingerprint);
- dep_node_index
+ dep_node_index
+ } else {
+ self.current.alloc_new_node(key, edges, fingerprint.unwrap_or(Fingerprint::ZERO))
+ }
}
fn promote_node_and_deps_to_current(&self, prev_index: SerializedDepNodeIndex) -> DepNodeIndex {
@@ -1246,19 +1253,15 @@ fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: F
assert_eq!(previous, fingerprint, "Unstable fingerprints for {:?}", key);
}
- /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it.
- /// Assumes that this is a node that has no equivalent in the previous dep-graph.
#[inline(always)]
- fn alloc_node(
+ fn record_node(
&self,
+ dep_node_index: DepNodeIndex,
key: DepNode,
- edges: EdgesVec,
- current_fingerprint: Fingerprint,
- ) -> DepNodeIndex {
- let dep_node_index = self.encoder.send(key, current_fingerprint, edges);
-
+ _current_fingerprint: Fingerprint,
+ ) {
#[cfg(debug_assertions)]
- self.record_edge(dep_node_index, key, current_fingerprint);
+ self.record_edge(dep_node_index, key, _current_fingerprint);
if let Some(ref nodes_in_current_session) = self.nodes_in_current_session {
outline(|| {
@@ -1267,6 +1270,20 @@ fn alloc_node(
}
});
}
+ }
+
+ /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it.
+ /// Assumes that this is a node that has no equivalent in the previous dep-graph.
+ #[inline(always)]
+ fn alloc_new_node(
+ &self,
+ key: DepNode,
+ edges: EdgesVec,
+ current_fingerprint: Fingerprint,
+ ) -> DepNodeIndex {
+ let dep_node_index = self.encoder.send_new(key, current_fingerprint, edges);
+
+ self.record_node(dep_node_index, key, current_fingerprint);
dep_node_index
}
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 7750d6d..7556a24 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -707,7 +707,8 @@ pub(crate) fn print_incremental_info(
}
}
- pub(crate) fn send(
+ /// Encodes a node that does not exists in the previous graph.
+ pub(crate) fn send_new(
&self,
node: DepNode,
fingerprint: Fingerprint,
@@ -718,6 +719,40 @@ pub(crate) fn send(
self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph)
}
+ /// Encodes a node that exists in the previous graph, but was re-executed.
+ ///
+ /// This will also ensure the dep node is colored either red or green.
+ pub(crate) fn send_and_color(
+ &self,
+ prev_index: SerializedDepNodeIndex,
+ colors: &DepNodeColorMap,
+ node: DepNode,
+ fingerprint: Fingerprint,
+ edges: EdgesVec,
+ is_green: bool,
+ ) -> DepNodeIndex {
+ let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
+ let node = NodeInfo { node, fingerprint, edges };
+
+ let mut status = self.status.lock();
+ let status = status.as_mut().unwrap();
+
+ // Check colors inside the lock to avoid racing when `send_promoted` is called concurrently
+ // on the same index.
+ match colors.get(prev_index) {
+ None => {
+ let dep_node_index = status.encode_node(&node, &self.record_graph);
+ colors.insert(
+ prev_index,
+ if is_green { DepNodeColor::Green(dep_node_index) } else { DepNodeColor::Red },
+ );
+ dep_node_index
+ }
+ Some(DepNodeColor::Green(dep_node_index)) => dep_node_index,
+ Some(DepNodeColor::Red) => panic!(),
+ }
+ }
+
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
/// the previous dep graph and expects all edges to already have a new dep node index assigned.
///
@@ -733,8 +768,8 @@ pub(crate) fn send_promoted(
let mut status = self.status.lock();
let status = status.as_mut().unwrap();
- // Check colors inside the lock to avoid racing when `send_promoted` is called concurrently
- // on the same index.
+ // Check colors inside the lock to avoid racing when `send_promoted` or `send_and_color`
+ // is called concurrently on the same index.
match colors.get(prev_index) {
None => {
let dep_node_index =
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 6dc8547..56bc826 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -2550,7 +2550,11 @@ pub(crate) fn find_cfg_stripped(&self, err: &mut Diag<'_>, segment: &Symbol, mod
.iter()
.filter_map(|item| {
let parent_module = self.opt_local_def_id(item.parent_module)?.to_def_id();
- Some(StrippedCfgItem { parent_module, name: item.name, cfg: item.cfg.clone() })
+ Some(StrippedCfgItem {
+ parent_module,
+ ident: item.ident,
+ cfg: item.cfg.clone(),
+ })
})
.collect::<Vec<_>>();
local_items.as_slice()
@@ -2558,12 +2562,12 @@ pub(crate) fn find_cfg_stripped(&self, err: &mut Diag<'_>, segment: &Symbol, mod
self.tcx.stripped_cfg_items(module.krate)
};
- for &StrippedCfgItem { parent_module, name, ref cfg } in symbols {
- if parent_module != module || name.name != *segment {
+ for &StrippedCfgItem { parent_module, ident, ref cfg } in symbols {
+ if parent_module != module || ident.name != *segment {
continue;
}
- let note = errors::FoundItemConfigureOut { span: name.span };
+ let note = errors::FoundItemConfigureOut { span: ident.span };
err.subdiagnostic(note);
if let MetaItemKind::List(nested) = &cfg.kind
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 5f0a2a5..180d6af 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -296,9 +296,6 @@ pub(crate) fn resolve_ident_in_lexical_scope(
) -> Option<LexicalScopeBinding<'ra>> {
assert!(ns == TypeNS || ns == ValueNS);
let orig_ident = ident;
- if ident.name == kw::Empty {
- return Some(LexicalScopeBinding::Res(Res::Err));
- }
let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
// FIXME(jseyfried) improve `Self` hygiene
let empty_span = ident.span.with_ctxt(SyntaxContext::root());
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index b62bc6c..c2761bd 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2238,7 +2238,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
.get(&def_id)
.is_some_and(|sig| sig.has_self),
None => {
- self.r.tcx.fn_arg_names(def_id).first().is_some_and(|&ident| {
+ self.r.tcx.fn_arg_idents(def_id).first().is_some_and(|&ident| {
matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
})
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 3ac6684..e147681 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1648,7 +1648,7 @@ pub fn into_outputs(self) -> ResolverOutputs {
.filter_map(|item| {
let parent_module =
self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id();
- Some(StrippedCfgItem { parent_module, name: item.name, cfg: item.cfg })
+ Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg })
})
.collect(),
);
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 9d6ae0a..e2f783d 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -469,8 +469,8 @@ fn declare_proc_macro(&mut self, id: NodeId) {
self.proc_macros.push(id)
}
- fn append_stripped_cfg_item(&mut self, parent_node: NodeId, name: Ident, cfg: ast::MetaItem) {
- self.stripped_cfg_items.push(StrippedCfgItem { parent_module: parent_node, name, cfg });
+ fn append_stripped_cfg_item(&mut self, parent_node: NodeId, ident: Ident, cfg: ast::MetaItem) {
+ self.stripped_cfg_items.push(StrippedCfgItem { parent_module: parent_node, ident, cfg });
}
fn registered_tools(&self) -> &RegisteredTools {
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index a087725..63772a3 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -7,6 +7,7 @@
# tidy-alphabetical-start
bitflags = "2.4.1"
getopts = "0.2"
+rand = "0.9.0"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 56b3fe2..bdd54a1 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1015,11 +1015,14 @@ pub fn file_for_writing(
&self,
outputs: &OutputFilenames,
flavor: OutputType,
- codegen_unit_name: Option<&str>,
+ codegen_unit_name: &str,
+ invocation_temp: Option<&str>,
) -> PathBuf {
match *self {
OutFileName::Real(ref path) => path.clone(),
- OutFileName::Stdout => outputs.temp_path(flavor, codegen_unit_name),
+ OutFileName::Stdout => {
+ outputs.temp_path_for_cgu(flavor, codegen_unit_name, invocation_temp)
+ }
}
}
@@ -1094,40 +1097,59 @@ fn output_path(&self, flavor: OutputType) -> PathBuf {
/// Gets the path where a compilation artifact of the given type for the
/// given codegen unit should be placed on disk. If codegen_unit_name is
/// None, a path distinct from those of any codegen unit will be generated.
- pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
+ pub fn temp_path_for_cgu(
+ &self,
+ flavor: OutputType,
+ codegen_unit_name: &str,
+ invocation_temp: Option<&str>,
+ ) -> PathBuf {
let extension = flavor.extension();
- self.temp_path_ext(extension, codegen_unit_name)
+ self.temp_path_ext_for_cgu(extension, codegen_unit_name, invocation_temp)
}
/// Like `temp_path`, but specifically for dwarf objects.
- pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
- self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
+ pub fn temp_path_dwo_for_cgu(
+ &self,
+ codegen_unit_name: &str,
+ invocation_temp: Option<&str>,
+ ) -> PathBuf {
+ self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp)
}
/// Like `temp_path`, but also supports things where there is no corresponding
/// OutputType, like noopt-bitcode or lto-bitcode.
- pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
- let mut extension = String::new();
+ pub fn temp_path_ext_for_cgu(
+ &self,
+ ext: &str,
+ codegen_unit_name: &str,
+ invocation_temp: Option<&str>,
+ ) -> PathBuf {
+ let mut extension = codegen_unit_name.to_string();
- if let Some(codegen_unit_name) = codegen_unit_name {
- extension.push_str(codegen_unit_name);
+ // Append `.{invocation_temp}` to ensure temporary files are unique.
+ if let Some(rng) = invocation_temp {
+ extension.push('.');
+ extension.push_str(rng);
}
+ // FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty.
+ // Append `.rcgu.{ext}`.
if !ext.is_empty() {
- if !extension.is_empty() {
- extension.push('.');
- extension.push_str(RUST_CGU_EXT);
- extension.push('.');
- }
-
+ extension.push('.');
+ extension.push_str(RUST_CGU_EXT);
+ extension.push('.');
extension.push_str(ext);
}
let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
-
self.with_directory_and_extension(temps_directory, &extension)
}
+ pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
+ let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
+ self.with_directory_and_extension(temps_directory, &ext)
+ }
+
pub fn with_extension(&self, extension: &str) -> PathBuf {
self.with_directory_and_extension(&self.out_directory, extension)
}
@@ -1144,10 +1166,11 @@ pub fn split_dwarf_path(
&self,
split_debuginfo_kind: SplitDebuginfo,
split_dwarf_kind: SplitDwarfKind,
- cgu_name: Option<&str>,
+ cgu_name: &str,
+ invocation_temp: Option<&str>,
) -> Option<PathBuf> {
- let obj_out = self.temp_path(OutputType::Object, cgu_name);
- let dwo_out = self.temp_path_dwo(cgu_name);
+ let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name, invocation_temp);
+ let dwo_out = self.temp_path_dwo_for_cgu(cgu_name, invocation_temp);
match (split_debuginfo_kind, split_dwarf_kind) {
(SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
// Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index fb4a437..1359f7e 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -6,6 +6,8 @@
use std::sync::atomic::AtomicBool;
use std::{env, fmt, io};
+use rand::{RngCore, rng};
+use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
@@ -203,6 +205,14 @@ pub struct Session {
target_filesearch: FileSearch,
host_filesearch: FileSearch,
+
+ /// A random string generated per invocation of rustc.
+ ///
+ /// This is prepended to all temporary files so that they do not collide
+ /// during concurrent invocations of rustc, or past invocations that were
+ /// preserved with a flag like `-C save-temps`, since these files may be
+ /// hard linked.
+ pub invocation_temp: Option<String>,
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
@@ -1117,6 +1127,12 @@ pub fn build_session(
let target_filesearch =
filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target);
let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host);
+
+ let invocation_temp = sopts
+ .incremental
+ .as_ref()
+ .map(|_| rng().next_u32().to_base_fixed_len(CASE_INSENSITIVE).to_string());
+
let sess = Session {
target,
host,
@@ -1140,6 +1156,7 @@ pub fn build_session(
expanded_args,
target_filesearch,
host_filesearch,
+ invocation_temp,
};
validate_commandline_args_with_session_available(&sess);
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9e6ba2e..c95c03b 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -116,9 +116,13 @@ pub struct SessionGlobals {
}
impl SessionGlobals {
- pub fn new(edition: Edition, sm_inputs: Option<SourceMapInputs>) -> SessionGlobals {
+ pub fn new(
+ edition: Edition,
+ extra_symbols: &[&'static str],
+ sm_inputs: Option<SourceMapInputs>,
+ ) -> SessionGlobals {
SessionGlobals {
- symbol_interner: symbol::Interner::fresh(),
+ symbol_interner: symbol::Interner::with_extra_symbols(extra_symbols),
span_interner: Lock::new(span_encoding::SpanInterner::default()),
metavar_spans: Default::default(),
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
@@ -129,6 +133,7 @@ pub fn new(edition: Edition, sm_inputs: Option<SourceMapInputs>) -> SessionGloba
pub fn create_session_globals_then<R>(
edition: Edition,
+ extra_symbols: &[&'static str],
sm_inputs: Option<SourceMapInputs>,
f: impl FnOnce() -> R,
) -> R {
@@ -137,7 +142,7 @@ pub fn create_session_globals_then<R>(
"SESSION_GLOBALS should never be overwritten! \
Use another thread if you need another SessionGlobals"
);
- let session_globals = SessionGlobals::new(edition, sm_inputs);
+ let session_globals = SessionGlobals::new(edition, extra_symbols, sm_inputs);
SESSION_GLOBALS.set(&session_globals, f)
}
@@ -156,7 +161,7 @@ pub fn create_session_if_not_set_then<R, F>(edition: Edition, f: F) -> R
F: FnOnce(&SessionGlobals) -> R,
{
if !SESSION_GLOBALS.is_set() {
- let session_globals = SessionGlobals::new(edition, None);
+ let session_globals = SessionGlobals::new(edition, &[], None);
SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f))
} else {
SESSION_GLOBALS.with(f)
@@ -172,7 +177,7 @@ pub fn with_session_globals<R, F>(f: F) -> R
/// Default edition, no source map.
pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
- create_session_globals_then(edition::DEFAULT_EDITION, None, f)
+ create_session_globals_then(edition::DEFAULT_EDITION, &[], None, f)
}
// If this ever becomes non thread-local, `decode_syntax_context`
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 31847ae..6bf7430 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1913,6 +1913,7 @@
simd_eq,
simd_expose_provenance,
simd_extract,
+ simd_extract_dyn,
simd_fabs,
simd_fcos,
simd_fexp,
@@ -1931,6 +1932,7 @@
simd_ge,
simd_gt,
simd_insert,
+ simd_insert_dyn,
simd_le,
simd_lt,
simd_masked_load,
@@ -2538,15 +2540,10 @@ struct SymbolIndex {}
}
impl Symbol {
- const fn new(n: u32) -> Self {
+ pub const fn new(n: u32) -> Self {
Symbol(SymbolIndex::from_u32(n))
}
- /// for use in Decoder only
- pub fn new_from_decoded(n: u32) -> Self {
- Self::new(n)
- }
-
/// Maps a string to its interned representation.
#[rustc_diagnostic_item = "SymbolIntern"]
pub fn intern(string: &str) -> Self {
@@ -2632,11 +2629,14 @@ struct InternerInner {
}
impl Interner {
- fn prefill(init: &[&'static str]) -> Self {
- Interner(Lock::new(InternerInner {
- arena: Default::default(),
- strings: init.iter().copied().collect(),
- }))
+ fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
+ let strings = FxIndexSet::from_iter(init.iter().copied().chain(extra.iter().copied()));
+ assert_eq!(
+ strings.len(),
+ init.len() + extra.len(),
+ "`init` or `extra` contain duplicate symbols",
+ );
+ Interner(Lock::new(InternerInner { arena: Default::default(), strings }))
}
#[inline]
@@ -2760,9 +2760,9 @@ pub fn can_be_raw(self) -> bool {
self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
}
- /// Is this symbol was interned in compiler's `symbols!` macro
- pub fn is_preinterned(self) -> bool {
- self.as_u32() < PREINTERNED_SYMBOLS_COUNT
+ /// Was this symbol predefined in the compiler's `symbols!` macro
+ pub fn is_predefined(self) -> bool {
+ self.as_u32() < PREDEFINED_SYMBOLS_COUNT
}
}
diff --git a/compiler/rustc_span/src/symbol/tests.rs b/compiler/rustc_span/src/symbol/tests.rs
index c6aa762..660d0d7 100644
--- a/compiler/rustc_span/src/symbol/tests.rs
+++ b/compiler/rustc_span/src/symbol/tests.rs
@@ -3,7 +3,7 @@
#[test]
fn interner_tests() {
- let i = Interner::prefill(&[]);
+ let i = Interner::prefill(&[], &[]);
// first one is zero:
assert_eq!(i.intern("dog"), Symbol::new(0));
// re-use gets the same entry:
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 38fcba4..b963e4a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1988,7 +1988,7 @@ fn note_conflicting_fn_args(
{
let closure: Vec<_> = self
.tcx
- .fn_arg_names(fn_def_id)
+ .fn_arg_idents(fn_def_id)
.iter()
.enumerate()
.map(|(i, ident)| {
@@ -3018,12 +3018,23 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
};
let needs_parens = traits.len() != 1;
- err.span_suggestion_verbose(
- span,
- "you can use `impl Trait` as the argument type",
- "impl ",
- Applicability::MaybeIncorrect,
- );
+ // Don't recommend impl Trait as a closure argument
+ if let Some(hir_id) = hir_id
+ && matches!(
+ self.tcx.parent_hir_node(hir_id),
+ hir::Node::Item(hir::Item {
+ kind: hir::ItemKind::Fn { .. },
+ ..
+ })
+ )
+ {
+ err.span_suggestion_verbose(
+ span,
+ "you can use `impl Trait` as the argument type",
+ "impl ",
+ Applicability::MaybeIncorrect,
+ );
+ }
let sugg = if !needs_parens {
vec![(span.shrink_to_lo(), format!("&{kw}"))]
} else {
@@ -5397,7 +5408,7 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
);
}
if let Some(new) =
- tcx.associated_items(data.impl_or_alias_def_id).find_by_name_and_kind(
+ tcx.associated_items(data.impl_or_alias_def_id).find_by_ident_and_kind(
tcx,
Ident::with_dummy_span(name),
ty::AssocKind::Type,
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
index 3a939df..d8dcd12 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
@@ -13,9 +13,9 @@
use rustc_type_ir::solve::NoSolution;
use tracing::{instrument, trace};
-use crate::solve::Certainty;
use crate::solve::delegate::SolverDelegate;
use crate::solve::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
+use crate::solve::{Certainty, deeply_normalize_for_diagnostics};
use crate::traits::{FulfillmentError, FulfillmentErrorCode, wf};
pub(super) fn fulfillment_error_for_no_solution<'tcx>(
@@ -151,7 +151,7 @@ fn find_best_leaf_obligation<'tcx>(
//
// We should probably fix the visitor to not do so instead, as this also
// means the leaf obligation may be incorrect.
- infcx
+ let obligation = infcx
.fudge_inference_if_ok(|| {
infcx
.visit_proof_tree(
@@ -161,7 +161,8 @@ fn find_best_leaf_obligation<'tcx>(
.break_value()
.ok_or(())
})
- .unwrap_or(obligation)
+ .unwrap_or(obligation);
+ deeply_normalize_for_diagnostics(infcx, obligation.param_env, obligation)
}
struct BestObligation<'tcx> {
@@ -291,6 +292,40 @@ fn detect_error_in_self_ty_normalization(
}
}
+ /// When a higher-ranked projection goal fails, check that the corresponding
+ /// higher-ranked trait goal holds or not. This is because the process of
+ /// instantiating and then re-canonicalizing the binder of the projection goal
+ /// forces us to be unable to see that the leak check failed in the nested
+ /// `NormalizesTo` goal, so we don't fall back to the rigid projection check
+ /// that should catch when a projection goal fails due to an unsatisfied trait
+ /// goal.
+ fn detect_trait_error_in_higher_ranked_projection(
+ &mut self,
+ goal: &inspect::InspectGoal<'_, 'tcx>,
+ ) -> ControlFlow<PredicateObligation<'tcx>> {
+ let tcx = goal.infcx().tcx;
+ if let Some(projection_clause) = goal.goal().predicate.as_projection_clause()
+ && !projection_clause.bound_vars().is_empty()
+ {
+ let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(tcx));
+ let obligation = Obligation::new(
+ tcx,
+ self.obligation.cause.clone(),
+ goal.goal().param_env,
+ deeply_normalize_for_diagnostics(goal.infcx(), goal.goal().param_env, pred),
+ );
+ self.with_derived_obligation(obligation, |this| {
+ goal.infcx().visit_proof_tree_at_depth(
+ goal.goal().with(tcx, pred),
+ goal.depth() + 1,
+ this,
+ )
+ })
+ } else {
+ ControlFlow::Continue(())
+ }
+ }
+
/// It is likely that `NormalizesTo` failed without any applicable candidates
/// because the alias is not well-formed.
///
@@ -360,7 +395,8 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
_ => return ControlFlow::Continue(()),
}
- let pred_kind = goal.goal().predicate.kind();
+
+ let pred = goal.goal().predicate;
let candidates = self.non_trivial_candidates(goal);
let candidate = match candidates.as_slice() {
@@ -374,7 +410,7 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
source: CandidateSource::Impl(impl_def_id),
result: _,
} = candidate.kind()
- && goal.infcx().tcx.do_not_recommend_impl(impl_def_id)
+ && tcx.do_not_recommend_impl(impl_def_id)
{
trace!("#[do_not_recommend] -> exit");
return ControlFlow::Break(self.obligation.clone());
@@ -382,12 +418,12 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
// for normalizes-to.
- let child_mode = match pred_kind.skip_binder() {
- ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
- ChildMode::Trait(pred_kind.rebind(pred))
+ let child_mode = match pred.kind().skip_binder() {
+ ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
+ ChildMode::Trait(pred.kind().rebind(trait_pred))
}
- ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => {
- ChildMode::Host(pred_kind.rebind(pred))
+ ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(host_pred)) => {
+ ChildMode::Host(pred.kind().rebind(host_pred))
}
ty::PredicateKind::NormalizesTo(normalizes_to)
if matches!(
@@ -395,7 +431,7 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst
) =>
{
- ChildMode::Trait(pred_kind.rebind(ty::TraitPredicate {
+ ChildMode::Trait(pred.kind().rebind(ty::TraitPredicate {
trait_ref: normalizes_to.alias.trait_ref(tcx),
polarity: ty::PredicatePolarity::Positive,
}))
@@ -429,10 +465,12 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
for nested_goal in nested_goals {
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
+ let nested_pred = nested_goal.goal().predicate;
+
let make_obligation = |cause| Obligation {
cause,
param_env: nested_goal.goal().param_env,
- predicate: nested_goal.goal().predicate,
+ predicate: nested_pred,
recursion_depth: self.obligation.recursion_depth + 1,
};
@@ -482,30 +520,21 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
// alias-relate may fail because the lhs or rhs can't be normalized,
// and therefore is treated as rigid.
- if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred_kind.no_bound_vars() {
- if let Some(obligation) = goal
- .infcx()
- .visit_proof_tree_at_depth(
- goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())),
- goal.depth() + 1,
- self,
- )
- .break_value()
- {
- return ControlFlow::Break(obligation);
- } else if let Some(obligation) = goal
- .infcx()
- .visit_proof_tree_at_depth(
- goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())),
- goal.depth() + 1,
- self,
- )
- .break_value()
- {
- return ControlFlow::Break(obligation);
- }
+ if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred.kind().no_bound_vars() {
+ goal.infcx().visit_proof_tree_at_depth(
+ goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())),
+ goal.depth() + 1,
+ self,
+ )?;
+ goal.infcx().visit_proof_tree_at_depth(
+ goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())),
+ goal.depth() + 1,
+ self,
+ )?;
}
+ self.detect_trait_error_in_higher_ranked_projection(goal)?;
+
ControlFlow::Break(self.obligation.clone())
}
}
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index 232357d..79fb044 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -253,20 +253,28 @@ fn cx(&self) -> TyCtxt<'tcx> {
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
- deeply_normalize_with_skipped_universes(
- self.at,
- ty,
- vec![None; ty.outer_exclusive_binder().as_usize()],
- )
- .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
+ let infcx = self.at.infcx;
+ infcx
+ .commit_if_ok(|_| {
+ deeply_normalize_with_skipped_universes(
+ self.at,
+ ty,
+ vec![None; ty.outer_exclusive_binder().as_usize()],
+ )
+ })
+ .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
- deeply_normalize_with_skipped_universes(
- self.at,
- ct,
- vec![None; ct.outer_exclusive_binder().as_usize()],
- )
- .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
+ let infcx = self.at.infcx;
+ infcx
+ .commit_if_ok(|_| {
+ deeply_normalize_with_skipped_universes(
+ self.at,
+ ct,
+ vec![None; ct.outer_exclusive_binder().as_usize()],
+ )
+ })
+ .unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
}
}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 349569d..8359121 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -669,30 +669,11 @@ fn project<'cx, 'tcx>(
match candidates {
ProjectionCandidateSet::Single(candidate) => {
- Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
+ confirm_candidate(selcx, obligation, candidate)
}
ProjectionCandidateSet::None => {
let tcx = selcx.tcx();
- let term = match tcx.def_kind(obligation.predicate.def_id) {
- DefKind::AssocTy => Ty::new_projection_from_args(
- tcx,
- obligation.predicate.def_id,
- obligation.predicate.args,
- )
- .into(),
- DefKind::AssocConst => ty::Const::new_unevaluated(
- tcx,
- ty::UnevaluatedConst::new(
- obligation.predicate.def_id,
- obligation.predicate.args,
- ),
- )
- .into(),
- kind => {
- bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id))
- }
- };
-
+ let term = obligation.predicate.to_term(tcx);
Ok(Projected::NoProgress(term))
}
// Error occurred while trying to processing impls.
@@ -1244,18 +1225,16 @@ fn confirm_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTermObligation<'tcx>,
candidate: ProjectionCandidate<'tcx>,
-) -> Progress<'tcx> {
+) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
debug!(?obligation, ?candidate, "confirm_candidate");
- let mut progress = match candidate {
+ let mut result = match candidate {
ProjectionCandidate::ParamEnv(poly_projection)
- | ProjectionCandidate::Object(poly_projection) => {
- confirm_param_env_candidate(selcx, obligation, poly_projection, false)
- }
-
- ProjectionCandidate::TraitDef(poly_projection) => {
- confirm_param_env_candidate(selcx, obligation, poly_projection, true)
- }
-
+ | ProjectionCandidate::Object(poly_projection) => Ok(Projected::Progress(
+ confirm_param_env_candidate(selcx, obligation, poly_projection, false),
+ )),
+ ProjectionCandidate::TraitDef(poly_projection) => Ok(Projected::Progress(
+ confirm_param_env_candidate(selcx, obligation, poly_projection, true),
+ )),
ProjectionCandidate::Select(impl_source) => {
confirm_select_candidate(selcx, obligation, impl_source)
}
@@ -1266,23 +1245,26 @@ fn confirm_candidate<'cx, 'tcx>(
// with new region variables, we need to resolve them to existing variables
// when possible for this to work. See `auto-trait-projection-recursion.rs`
// for a case where this matters.
- if progress.term.has_infer_regions() {
+ if let Ok(Projected::Progress(progress)) = &mut result
+ && progress.term.has_infer_regions()
+ {
progress.term = progress.term.fold_with(&mut OpportunisticRegionResolver::new(selcx.infcx));
}
- progress
+
+ result
}
fn confirm_select_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTermObligation<'tcx>,
impl_source: Selection<'tcx>,
-) -> Progress<'tcx> {
+) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
match impl_source {
ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, data) => {
let tcx = selcx.tcx();
let trait_def_id = obligation.predicate.trait_def_id(tcx);
- if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) {
+ let progress = if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) {
confirm_coroutine_candidate(selcx, obligation, data)
} else if tcx.is_lang_item(trait_def_id, LangItem::Future) {
confirm_future_candidate(selcx, obligation, data)
@@ -1304,7 +1286,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
confirm_async_fn_kind_helper_candidate(selcx, obligation, data)
} else {
confirm_builtin_candidate(selcx, obligation, data)
- }
+ };
+ Ok(Projected::Progress(progress))
}
ImplSource::Builtin(BuiltinImplSource::Object { .. }, _)
| ImplSource::Param(..)
@@ -2000,7 +1983,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTermObligation<'tcx>,
impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
-) -> Progress<'tcx> {
+) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
let tcx = selcx.tcx();
let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
@@ -2011,19 +1994,33 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let param_env = obligation.param_env;
let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
Ok(assoc_ty) => assoc_ty,
- Err(guar) => return Progress::error(tcx, guar),
+ Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))),
};
+
+ // This means that the impl is missing a definition for the
+ // associated type. This is either because the associate item
+ // has impossible-to-satisfy predicates (since those were
+ // allowed in <https://github.com/rust-lang/rust/pull/135480>),
+ // or because the impl is literally missing the definition.
if !assoc_ty.item.defaultness(tcx).has_value() {
- // This means that the impl is missing a definition for the
- // associated type. This error will be reported by the type
- // checker method `check_impl_items_against_trait`, so here we
- // just return Error.
debug!(
"confirm_impl_candidate: no associated type {:?} for {:?}",
assoc_ty.item.name, obligation.predicate
);
- return Progress { term: Ty::new_misc_error(tcx).into(), obligations: nested };
+ if tcx.impl_self_is_guaranteed_unsized(impl_def_id) {
+ // We treat this projection as rigid here, which is represented via
+ // `Projected::NoProgress`. This will ensure that the projection is
+ // checked for well-formedness, and it's either satisfied by a trivial
+ // where clause in its env or it results in an error.
+ return Ok(Projected::NoProgress(obligation.predicate.to_term(tcx)));
+ } else {
+ return Ok(Projected::Progress(Progress {
+ term: Ty::new_misc_error(tcx).into(),
+ obligations: nested,
+ }));
+ }
}
+
// If we're trying to normalize `<Vec<u32> as X>::A<S>` using
//`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
//
@@ -2033,6 +2030,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args);
let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
+
let term: ty::EarlyBinder<'tcx, ty::Term<'tcx>> = if is_const {
let did = assoc_ty.item.def_id;
let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
@@ -2041,7 +2039,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
} else {
tcx.type_of(assoc_ty.item.def_id).map_bound(|ty| ty.into())
};
- if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
+
+ let progress = if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
let err = Ty::new_error_with_message(
tcx,
obligation.cause.span,
@@ -2051,7 +2050,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
} else {
assoc_ty_own_obligations(selcx, obligation, &mut nested);
Progress { term: term.instantiate(tcx, args), obligations: nested }
- }
+ };
+ Ok(Projected::Progress(progress))
}
// Get obligations corresponding to the predicates from the where-clause of the
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 9dc4f11..31d69ee 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -3,6 +3,7 @@
use rustc_hir::LangItem;
use rustc_hir::def::DefKind;
use rustc_index::bit_set::DenseBitSet;
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::{
@@ -312,6 +313,61 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe
unsizing_params
}
+fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) -> bool {
+ debug_assert_eq!(tcx.def_kind(impl_def_id), DefKind::Impl { of_trait: true });
+
+ let infcx = tcx.infer_ctxt().ignoring_regions().build(ty::TypingMode::non_body_analysis());
+
+ let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
+ let cause = traits::ObligationCause::dummy();
+ let param_env = tcx.param_env(impl_def_id);
+
+ let tail = tcx.struct_tail_raw(
+ tcx.type_of(impl_def_id).instantiate_identity(),
+ |ty| {
+ ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| {
+ Ty::new_error_with_message(
+ tcx,
+ tcx.def_span(impl_def_id),
+ "struct tail should be computable",
+ )
+ })
+ },
+ || (),
+ );
+
+ match tail.kind() {
+ ty::Dynamic(_, _, ty::Dyn) | ty::Slice(_) | ty::Str => true,
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Adt(_, _)
+ | ty::Foreign(_)
+ | ty::Array(_, _)
+ | ty::Pat(_, _)
+ | ty::RawPtr(_, _)
+ | ty::Ref(_, _, _)
+ | ty::FnDef(_, _)
+ | ty::FnPtr(_, _)
+ | ty::UnsafeBinder(_)
+ | ty::Closure(_, _)
+ | ty::CoroutineClosure(_, _)
+ | ty::Coroutine(_, _)
+ | ty::CoroutineWitness(_, _)
+ | ty::Never
+ | ty::Tuple(_)
+ | ty::Alias(_, _)
+ | ty::Param(_)
+ | ty::Bound(_, _)
+ | ty::Placeholder(_)
+ | ty::Infer(_)
+ | ty::Error(_)
+ | ty::Dynamic(_, _, ty::DynStar) => false,
+ }
+}
+
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
asyncness,
@@ -320,6 +376,7 @@ pub(crate) fn provide(providers: &mut Providers) {
param_env_normalized_for_post_analysis,
defaultness,
unsizing_params_for_adt,
+ impl_self_is_guaranteed_unsized,
..*providers
};
}
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 59c2d3c..6e6c405 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -155,6 +155,39 @@ fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
fn is_known_rigid(self) -> bool {
self.kind().is_known_rigid()
}
+
+ fn is_guaranteed_unsized_raw(self) -> bool {
+ match self.kind() {
+ ty::Dynamic(_, _, ty::Dyn) | ty::Slice(_) | ty::Str => true,
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Adt(_, _)
+ | ty::Foreign(_)
+ | ty::Array(_, _)
+ | ty::Pat(_, _)
+ | ty::RawPtr(_, _)
+ | ty::Ref(_, _, _)
+ | ty::FnDef(_, _)
+ | ty::FnPtr(_, _)
+ | ty::UnsafeBinder(_)
+ | ty::Closure(_, _)
+ | ty::CoroutineClosure(_, _)
+ | ty::Coroutine(_, _)
+ | ty::CoroutineWitness(_, _)
+ | ty::Never
+ | ty::Tuple(_)
+ | ty::Alias(_, _)
+ | ty::Param(_)
+ | ty::Bound(_, _)
+ | ty::Placeholder(_)
+ | ty::Infer(_)
+ | ty::Error(_)
+ | ty::Dynamic(_, _, ty::DynStar) => false,
+ }
+ }
}
pub trait Tys<I: Interner<Tys = Self>>:
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index fce93b7..a9e6764 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -255,6 +255,8 @@ fn explicit_implied_const_bounds(
def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
+ fn impl_self_is_guaranteed_unsized(self, def_id: Self::DefId) -> bool;
+
fn has_target_features(self, def_id: Self::DefId) -> bool;
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 4e2baca..bdc61e95 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -1,12 +1,12 @@
// tidy-alphabetical-start
#![allow(rustc::usage_of_ty_tykind)]
#![allow(rustc::usage_of_type_ir_inherent)]
+#![allow(rustc::usage_of_type_ir_traits)]
#![cfg_attr(
feature = "nightly",
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
)]
#![cfg_attr(feature = "nightly", allow(internal_features))]
-#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_traits))]
// tidy-alphabetical-end
extern crate self as rustc_type_ir;
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 3aec480..4e9b87f 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -83,8 +83,11 @@ pub enum GoalSource {
/// Instantiating a higher-ranked goal and re-proving it.
InstantiateHigherRanked,
/// Predicate required for an alias projection to be well-formed.
- /// This is used in two places: projecting to an opaque whose hidden type
- /// is already registered in the opaque type storage, and for rigid projections.
+ /// This is used in three places:
+ /// 1. projecting to an opaque whose hidden type is already registered in
+ /// the opaque type storage,
+ /// 2. for rigid projections's trait goal,
+ /// 3. for GAT where clauses.
AliasWellFormed,
/// In case normalizing aliases in nested goals cycles, eagerly normalizing these
/// aliases in the context of the parent may incorrectly change the cycle kind.
diff --git a/library/Cargo.lock b/library/Cargo.lock
index ad634e9..d035ca6 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -67,9 +67,9 @@
[[package]]
name = "compiler_builtins"
-version = "0.1.152"
+version = "0.1.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2153cf213eb259361567720ce55f6446f17acd0ccca87fb6dc05360578228a58"
+checksum = "926ef6a360c15a911023352fd6969c51605d70495406f735beb1ca0257448e59"
dependencies = [
"cc",
"rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 1d2dd1e..ee8cb9d 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@
[dependencies]
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.153", features = ['rustc-dep-of-std'] }
[features]
compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 1e03a19..e1cc4ba 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -16,22 +16,22 @@
// otherwise.
#[rustc_allocator]
#[rustc_nounwind]
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
#[rustc_deallocator]
#[rustc_nounwind]
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
#[rustc_reallocator]
#[rustc_nounwind]
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
#[rustc_allocator_zeroed]
#[rustc_nounwind]
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
static __rust_no_alloc_shim_is_unstable: u8;
}
@@ -360,7 +360,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
// This is the magic symbol to call the global alloc error handler. rustc generates
// it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
// default implementations below (`__rdl_oom`) otherwise.
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
}
@@ -427,7 +427,7 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
unsafe extern "Rust" {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
static __rust_alloc_error_handler_should_panic: u8;
}
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 4644e37..4536f55 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -952,7 +952,7 @@ pub unsafe fn assume_init(self) -> Box<T, A> {
/// assert_eq!(*x, i);
/// }
/// ```
- #[stable(feature = "box_uninit_write", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "box_uninit_write", since = "1.87.0")]
#[inline]
pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
unsafe {
diff --git a/library/alloc/src/collections/btree/set_val.rs b/library/alloc/src/collections/btree/set_val.rs
index cf30160..5037b65 100644
--- a/library/alloc/src/collections/btree/set_val.rs
+++ b/library/alloc/src/collections/btree/set_val.rs
@@ -9,7 +9,7 @@
/// Returns `true` only for type `SetValZST`, `false` for all other types (blanket implementation).
/// `TypeId` requires a `'static` lifetime, use of this trait avoids that restriction.
///
-/// [`TypeId`]: std::any::TypeId
+/// [`TypeId`]: core::any::TypeId
pub(super) trait IsSetVal {
fn is_set_val() -> bool;
}
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 3183268..cc42a12 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1151,7 +1151,7 @@ pub fn retain_mut<F>(&mut self, mut f: F)
/// assert_eq!(evens.into_iter().collect::<Vec<_>>(), vec![2, 4, 6, 8, 14]);
/// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 9, 11, 13, 15]);
/// ```
- #[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "extract_if", since = "1.87.0")]
pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where
F: FnMut(&mut T) -> bool,
@@ -1931,7 +1931,7 @@ pub fn back_mut(&mut self) -> Option<&mut T> {
}
/// An iterator produced by calling `extract_if` on LinkedList.
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ExtractIf<
'a,
@@ -1946,7 +1946,7 @@ pub struct ExtractIf<
old_len: usize,
}
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
where
F: FnMut(&mut T) -> bool,
@@ -1975,7 +1975,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
}
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
impl<T: fmt::Debug, F> fmt::Debug for ExtractIf<'_, T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("ExtractIf").field(&self.list).finish()
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 0485866..e70e6ca 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -104,6 +104,7 @@
#![feature(async_iterator)]
#![feature(bstr)]
#![feature(bstr_internals)]
+#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]
#![feature(coerce_unsized)]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 9236f5c..9a161d0 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1043,7 +1043,7 @@ pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
#[inline]
#[must_use = "`self` will be dropped if the result is not used"]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
pub const fn into_bytes(self) -> Vec<u8> {
self.vec
@@ -1062,7 +1062,7 @@ pub const fn into_bytes(self) -> Vec<u8> {
#[must_use]
#[stable(feature = "string_as_str", since = "1.7.0")]
#[rustc_diagnostic_item = "string_as_str"]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn as_str(&self) -> &str {
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
// at construction.
@@ -1085,7 +1085,7 @@ pub const fn as_str(&self) -> &str {
#[must_use]
#[stable(feature = "string_as_str", since = "1.7.0")]
#[rustc_diagnostic_item = "string_as_mut_str"]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn as_mut_str(&mut self) -> &mut str {
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
// at construction.
@@ -1134,7 +1134,7 @@ pub fn push_str(&mut self, string: &str) {
/// assert_eq!(string, "abcdecdeabecde");
/// ```
#[cfg(not(no_global_oom_handling))]
- #[stable(feature = "string_extend_from_within", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "string_extend_from_within", since = "1.87.0")]
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
@@ -1159,7 +1159,7 @@ pub fn extend_from_within<R>(&mut self, src: R)
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn capacity(&self) -> usize {
self.vec.capacity()
}
@@ -1401,11 +1401,14 @@ pub fn shrink_to(&mut self, min_capacity: usize) {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push(&mut self, ch: char) {
- match ch.len_utf8() {
- 1 => self.vec.push(ch as u8),
- _ => {
- self.vec.extend_from_slice(ch.encode_utf8(&mut [0; char::MAX_LEN_UTF8]).as_bytes())
- }
+ let len = self.len();
+ let ch_len = ch.len_utf8();
+ self.reserve(ch_len);
+
+ // SAFETY: Just reserved capacity for at least the length needed to encode `ch`.
+ unsafe {
+ core::char::encode_utf8_raw_unchecked(ch as u32, self.vec.as_mut_ptr().add(self.len()));
+ self.vec.set_len(len + ch_len);
}
}
@@ -1425,7 +1428,7 @@ pub fn push(&mut self, ch: char) {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn as_bytes(&self) -> &[u8] {
self.vec.as_slice()
}
@@ -1702,24 +1705,31 @@ fn drop(&mut self) {
#[rustc_confusables("set")]
pub fn insert(&mut self, idx: usize, ch: char) {
assert!(self.is_char_boundary(idx));
- let mut bits = [0; char::MAX_LEN_UTF8];
- let bits = ch.encode_utf8(&mut bits).as_bytes();
- unsafe {
- self.insert_bytes(idx, bits);
- }
- }
-
- #[cfg(not(no_global_oom_handling))]
- unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
let len = self.len();
- let amt = bytes.len();
- self.vec.reserve(amt);
+ let ch_len = ch.len_utf8();
+ self.reserve(ch_len);
+ // SAFETY: Move the bytes starting from `idx` to their new location `ch_len`
+ // bytes ahead. This is safe because sufficient capacity was reserved, and `idx`
+ // is a char boundary.
unsafe {
- ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
- ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
- self.vec.set_len(len + amt);
+ ptr::copy(
+ self.vec.as_ptr().add(idx),
+ self.vec.as_mut_ptr().add(idx + ch_len),
+ len - idx,
+ );
+ }
+
+ // SAFETY: Encode the character into the vacated region if `idx != len`,
+ // or into the uninitialized spare capacity otherwise.
+ unsafe {
+ core::char::encode_utf8_raw_unchecked(ch as u32, self.vec.as_mut_ptr().add(idx));
+ }
+
+ // SAFETY: Update the length to include the newly added bytes.
+ unsafe {
+ self.vec.set_len(len + ch_len);
}
}
@@ -1749,8 +1759,27 @@ unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
pub fn insert_str(&mut self, idx: usize, string: &str) {
assert!(self.is_char_boundary(idx));
+ let len = self.len();
+ let amt = string.len();
+ self.reserve(amt);
+
+ // SAFETY: Move the bytes starting from `idx` to their new location `amt` bytes
+ // ahead. This is safe because sufficient capacity was just reserved, and `idx`
+ // is a char boundary.
unsafe {
- self.insert_bytes(idx, string.as_bytes());
+ ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
+ }
+
+ // SAFETY: Copy the new string slice into the vacated region if `idx != len`,
+ // or into the uninitialized spare capacity otherwise. The borrow checker
+ // ensures that the source and destination do not overlap.
+ unsafe {
+ ptr::copy_nonoverlapping(string.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
+ }
+
+ // SAFETY: Update the length to include the newly added bytes.
+ unsafe {
+ self.vec.set_len(len + amt);
}
}
@@ -1779,7 +1808,7 @@ pub fn insert_str(&mut self, idx: usize, string: &str) {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
&mut self.vec
}
@@ -1801,7 +1830,7 @@ pub fn insert_str(&mut self, idx: usize, string: &str) {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_confusables("length", "size")]
pub const fn len(&self) -> usize {
self.vec.len()
@@ -1821,7 +1850,7 @@ pub const fn len(&self) -> usize {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
@@ -3140,7 +3169,7 @@ fn from(string: String) -> Vec<u8> {
}
}
-#[stable(feature = "try_from_vec_u8_for_string", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "try_from_vec_u8_for_string", since = "1.87.0")]
impl TryFrom<Vec<u8>> for String {
type Error = FromUtf8Error;
/// Converts the given [`Vec<u8>`] into a [`String`] if it contains valid UTF-8 data.
diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs
index be869553..8a591a8 100644
--- a/library/alloc/src/vec/extract_if.rs
+++ b/library/alloc/src/vec/extract_if.rs
@@ -15,7 +15,7 @@
/// let mut v = vec![0, 1, 2];
/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0);
/// ```
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
#[derive(Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ExtractIf<
@@ -57,7 +57,7 @@ pub fn allocator(&self) -> &A {
}
}
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
where
F: FnMut(&mut T) -> bool,
@@ -93,7 +93,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
}
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A> {
fn drop(&mut self) {
unsafe {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index e6867fe..68e4add 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -66,7 +66,7 @@
use core::slice::{self, SliceIndex};
use core::{fmt, intrinsics};
-#[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "extract_if", since = "1.87.0")]
pub use self::extract_if::ExtractIf;
use crate::alloc::{Allocator, Global};
use crate::borrow::{Cow, ToOwned};
@@ -1267,7 +1267,7 @@ pub fn into_parts_with_alloc(self) -> (NonNull<T>, usize, usize, A) {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn capacity(&self) -> usize {
self.buf.capacity()
}
@@ -1582,7 +1582,7 @@ pub fn truncate(&mut self, len: usize) {
#[inline]
#[stable(feature = "vec_as_slice", since = "1.7.0")]
#[rustc_diagnostic_item = "vec_as_slice"]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn as_slice(&self) -> &[T] {
// SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
// `len` containing properly-initialized `T`s. Data must not be mutated for the returned
@@ -1614,7 +1614,7 @@ pub const fn as_slice(&self) -> &[T] {
#[inline]
#[stable(feature = "vec_as_slice", since = "1.7.0")]
#[rustc_diagnostic_item = "vec_as_mut_slice"]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn as_mut_slice(&mut self) -> &mut [T] {
// SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
// size `len` containing properly-initialized `T`s. Data must not be accessed through any
@@ -1686,7 +1686,7 @@ pub const fn as_mut_slice(&mut self) -> &mut [T] {
/// [`as_ptr`]: Vec::as_ptr
/// [`as_non_null`]: Vec::as_non_null
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_never_returns_null_ptr]
#[rustc_as_ptr]
#[inline]
@@ -1749,7 +1749,7 @@ pub const fn as_ptr(&self) -> *const T {
/// [`as_ptr`]: Vec::as_ptr
/// [`as_non_null`]: Vec::as_non_null
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_never_returns_null_ptr]
#[rustc_as_ptr]
#[inline]
@@ -2700,7 +2700,7 @@ pub fn clear(&mut self) {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_confusables("length", "size")]
pub const fn len(&self) -> usize {
let len = self.len;
@@ -2726,7 +2726,7 @@ pub const fn len(&self) -> usize {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "vec_is_empty"]
- #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
@@ -3715,7 +3715,7 @@ pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoI
/// assert_eq!(items, vec![0, 0, 0, 0, 0, 0, 0, 2, 2, 2]);
/// assert_eq!(ones.len(), 3);
/// ```
- #[stable(feature = "extract_if", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "extract_if", since = "1.87.0")]
pub fn extract_if<F, R>(&mut self, range: R, filter: F) -> ExtractIf<'_, T, F, A>
where
F: FnMut(&mut T) -> bool,
diff --git a/library/alloctests/benches/string.rs b/library/alloctests/benches/string.rs
index 3d79ab7..0bbec12 100644
--- a/library/alloctests/benches/string.rs
+++ b/library/alloctests/benches/string.rs
@@ -4,7 +4,7 @@
#[bench]
fn bench_with_capacity(b: &mut Bencher) {
- b.iter(|| String::with_capacity(100));
+ b.iter(|| String::with_capacity(black_box(100)));
}
#[bench]
@@ -12,7 +12,8 @@ fn bench_push_str(b: &mut Bencher) {
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
b.iter(|| {
let mut r = String::new();
- r.push_str(s);
+ black_box(&mut r).push_str(black_box(s));
+ r
});
}
@@ -24,8 +25,9 @@ fn bench_push_str_one_byte(b: &mut Bencher) {
b.iter(|| {
let mut r = String::new();
for _ in 0..REPETITIONS {
- r.push_str("a")
+ black_box(&mut r).push_str(black_box("a"));
}
+ r
});
}
@@ -35,8 +37,9 @@ fn bench_push_char_one_byte(b: &mut Bencher) {
b.iter(|| {
let mut r = String::new();
for _ in 0..REPETITIONS {
- r.push('a')
+ black_box(&mut r).push(black_box('a'));
}
+ r
});
}
@@ -46,8 +49,9 @@ fn bench_push_char_two_bytes(b: &mut Bencher) {
b.iter(|| {
let mut r = String::new();
for _ in 0..REPETITIONS {
- r.push('â')
+ black_box(&mut r).push(black_box('â'));
}
+ r
});
}
@@ -57,34 +61,26 @@ fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
Lorem ipsum dolor sit amet, consectetur. ";
assert_eq!(100, s.len());
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
+ b.iter(|| String::from_utf8_lossy(black_box(s)));
}
#[bench]
fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
assert_eq!(100, s.len());
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
+ b.iter(|| String::from_utf8_lossy(black_box(s)));
}
#[bench]
fn from_utf8_lossy_invalid(b: &mut Bencher) {
let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
+ b.iter(|| String::from_utf8_lossy(black_box(s)));
}
#[bench]
fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
let s = repeat(0xf5).take(100).collect::<Vec<_>>();
- b.iter(|| {
- let _ = String::from_utf8_lossy(&s);
- });
+ b.iter(|| String::from_utf8_lossy(black_box(&s)));
}
#[bench]
@@ -96,8 +92,8 @@ fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
r.push_str(s);
assert_eq!(r.len(), r.capacity());
b.iter(|| {
- let mut r = String::with_capacity(s.len());
- r.push_str(s);
+ let mut r = String::with_capacity(black_box(s.len()));
+ r.push_str(black_box(s));
r.shrink_to_fit();
r
});
@@ -107,21 +103,21 @@ fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
fn bench_from_str(b: &mut Bencher) {
let s = "Hello there, the quick brown fox jumped over the lazy dog! \
Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| String::from(s))
+ b.iter(|| String::from(black_box(s)))
}
#[bench]
fn bench_from(b: &mut Bencher) {
let s = "Hello there, the quick brown fox jumped over the lazy dog! \
Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| String::from(s))
+ b.iter(|| String::from(black_box(s)))
}
#[bench]
fn bench_to_string(b: &mut Bencher) {
let s = "Hello there, the quick brown fox jumped over the lazy dog! \
Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| s.to_string())
+ b.iter(|| black_box(s).to_string())
}
#[bench]
@@ -129,7 +125,7 @@ fn bench_insert_char_short(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
- black_box(&mut x).insert(6, black_box(' '));
+ black_box(&mut x).insert(black_box(6), black_box(' '));
x
})
}
@@ -139,7 +135,7 @@ fn bench_insert_char_long(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
- black_box(&mut x).insert(6, black_box('❤'));
+ black_box(&mut x).insert(black_box(6), black_box('❤'));
x
})
}
@@ -149,7 +145,7 @@ fn bench_insert_str_short(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
- black_box(&mut x).insert_str(6, black_box(" "));
+ black_box(&mut x).insert_str(black_box(6), black_box(" "));
x
})
}
@@ -159,7 +155,7 @@ fn bench_insert_str_long(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
- black_box(&mut x).insert_str(6, black_box(" rustic "));
+ black_box(&mut x).insert_str(black_box(6), black_box(" rustic "));
x
})
}
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index b60826e..fe61f55 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -32,8 +32,6 @@
'cfg(bootstrap)',
'cfg(no_fp_fmt_parse)',
'cfg(stdarch_intel_sde)',
- # #[cfg(bootstrap)]
- 'cfg(target_feature, values("vector-enhancements-1"))',
# core use #[path] imports to portable-simd `core_simd` crate
# and to stdarch `core_arch` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 28329bb..efa7bed 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -55,12 +55,16 @@
from_trusted_iterator(repeat_n(val, N))
}
-/// Creates an array of type [T; N], where each element `T` is the returned value from `cb`
-/// using that element's index.
+/// Creates an array where each element is produced by calling `f` with
+/// that element's index while walking forward through the array.
///
-/// # Arguments
+/// This is essentially the same as writing
+/// ```text
+/// [f(0), f(1), f(2), …, f(N - 2), f(N - 1)]
+/// ```
+/// and is similar to `(0..i).map(f)`, just for arrays not iterators.
///
-/// * `cb`: Callback where the passed argument is the current array index.
+/// If `N == 0`, this produces an empty array without ever calling `f`.
///
/// # Example
///
@@ -82,13 +86,30 @@
/// // indexes are: 0 1 2 3 4
/// assert_eq!(bool_arr, [true, false, true, false, true]);
/// ```
+///
+/// You can also capture things, for example to create an array full of clones
+/// where you can't just use `[item; N]` because it's not `Copy`:
+/// ```
+/// # // TBH `array::repeat` would be better for this, but it's not stable yet.
+/// let my_string = String::from("Hello");
+/// let clones: [String; 42] = std::array::from_fn(|_| my_string.clone());
+/// assert!(clones.iter().all(|x| *x == my_string));
+/// ```
+///
+/// The array is generated in ascending index order, starting from the front
+/// and going towards the back, so you can use closures with mutable state:
+/// ```
+/// let mut state = 1;
+/// let a = std::array::from_fn(|_| { let x = state; state *= 2; x });
+/// assert_eq!(a, [1, 2, 4, 8, 16, 32]);
+/// ```
#[inline]
#[stable(feature = "array_from_fn", since = "1.63.0")]
-pub fn from_fn<T, const N: usize, F>(cb: F) -> [T; N]
+pub fn from_fn<T, const N: usize, F>(f: F) -> [T; N]
where
F: FnMut(usize) -> T,
{
- try_from_fn(NeverShortCircuit::wrap_mut_1(cb)).0
+ try_from_fn(NeverShortCircuit::wrap_mut_1(f)).0
}
/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 09117e4..17231df 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1156,7 +1156,9 @@ pub fn as_ptr(&self) -> *mut T {
/// Since this method borrows `RefCell` mutably, it is statically guaranteed
/// that no borrows to the underlying data exist. The dynamic checks inherent
/// in [`borrow_mut`] and most other methods of `RefCell` are therefore
- /// unnecessary.
+ /// unnecessary. Note that this method does not reset the borrowing state if borrows were previously leaked
+ /// (e.g., via [`forget()`] on a [`Ref`] or [`RefMut`]). For that purpose,
+ /// consider using the unstable [`undo_leak`] method.
///
/// This method can only be called if `RefCell` can be mutably borrowed,
/// which in general is only the case directly after the `RefCell` has
@@ -1167,6 +1169,8 @@ pub fn as_ptr(&self) -> *mut T {
/// Use [`borrow_mut`] to get mutable access to the underlying data then.
///
/// [`borrow_mut`]: RefCell::borrow_mut()
+ /// [`forget()`]: mem::forget
+ /// [`undo_leak`]: RefCell::undo_leak()
///
/// # Examples
///
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index fa58495..042925a 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -337,7 +337,7 @@ pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
/// '1'.is_digit(1);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_char_classify", since = "1.87.0")]
#[inline]
pub const fn is_digit(self, radix: u32) -> bool {
self.to_digit(radix).is_some()
@@ -886,7 +886,7 @@ pub const fn is_uppercase(self) -> bool {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_char_classify", since = "1.87.0")]
#[inline]
pub const fn is_whitespace(self) -> bool {
match self {
@@ -1806,39 +1806,71 @@ const fn len_utf16(code: u32) -> usize {
#[inline]
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
let len = len_utf8(code);
- match (len, &mut *dst) {
- (1, [a, ..]) => {
- *a = code as u8;
- }
- (2, [a, b, ..]) => {
- *a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
- *b = (code & 0x3F) as u8 | TAG_CONT;
- }
- (3, [a, b, c, ..]) => {
- *a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
- *b = (code >> 6 & 0x3F) as u8 | TAG_CONT;
- *c = (code & 0x3F) as u8 | TAG_CONT;
- }
- (4, [a, b, c, d, ..]) => {
- *a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
- *b = (code >> 12 & 0x3F) as u8 | TAG_CONT;
- *c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
- *d = (code & 0x3F) as u8 | TAG_CONT;
- }
- _ => {
- const_panic!(
- "encode_utf8: buffer does not have enough bytes to encode code point",
- "encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
- code: u32 = code,
- len: usize = len,
- dst_len: usize = dst.len(),
- )
- }
- };
+ if dst.len() < len {
+ const_panic!(
+ "encode_utf8: buffer does not have enough bytes to encode code point",
+ "encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
+ code: u32 = code,
+ len: usize = len,
+ dst_len: usize = dst.len(),
+ );
+ }
+
+ // SAFETY: `dst` is checked to be at least the length needed to encode the codepoint.
+ unsafe { encode_utf8_raw_unchecked(code, dst.as_mut_ptr()) };
+
// SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
}
+/// Encodes a raw `u32` value as UTF-8 into the byte buffer pointed to by `dst`.
+///
+/// Unlike `char::encode_utf8`, this method also handles codepoints in the surrogate range.
+/// (Creating a `char` in the surrogate range is UB.)
+/// The result is valid [generalized UTF-8] but not valid UTF-8.
+///
+/// [generalized UTF-8]: https://simonsapin.github.io/wtf-8/#generalized-utf8
+///
+/// # Safety
+///
+/// The behavior is undefined if the buffer pointed to by `dst` is not
+/// large enough to hold the encoded codepoint. A buffer of length four
+/// is large enough to encode any `char`.
+///
+/// For a safe version of this function, see the [`encode_utf8_raw`] function.
+#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
+#[doc(hidden)]
+#[inline]
+pub const unsafe fn encode_utf8_raw_unchecked(code: u32, dst: *mut u8) {
+ let len = len_utf8(code);
+ // SAFETY: The caller must guarantee that the buffer pointed to by `dst`
+ // is at least `len` bytes long.
+ unsafe {
+ match len {
+ 1 => {
+ *dst = code as u8;
+ }
+ 2 => {
+ *dst = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
+ *dst.add(1) = (code & 0x3F) as u8 | TAG_CONT;
+ }
+ 3 => {
+ *dst = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
+ *dst.add(1) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ *dst.add(2) = (code & 0x3F) as u8 | TAG_CONT;
+ }
+ 4 => {
+ *dst = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
+ *dst.add(1) = (code >> 12 & 0x3F) as u8 | TAG_CONT;
+ *dst.add(2) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ *dst.add(3) = (code & 0x3F) as u8 | TAG_CONT;
+ }
+ // SAFETY: `char` always takes between 1 and 4 bytes to encode in UTF-8.
+ _ => crate::hint::unreachable_unchecked(),
+ }
+ }
+}
+
/// Encodes a raw `u32` value as native endian UTF-16 into the provided `u16` buffer,
/// and then returns the subslice of the buffer that contains the encoded character.
///
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 088c709..5b9f0e2 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -38,7 +38,7 @@
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
pub use self::methods::encode_utf16_raw; // perma-unstable
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
-pub use self::methods::encode_utf8_raw; // perma-unstable
+pub use self::methods::{encode_utf8_raw, encode_utf8_raw_unchecked}; // perma-unstable
#[rustfmt::skip]
use crate::ascii;
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index e0ac0bf..c237ac8 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -216,7 +216,7 @@ fn clone_from(&mut self, source: &Self) {
/// Use closures allow captured values to be automatically used.
/// This is similar to have a closure that you would call `.use` over each captured value.
#[unstable(feature = "ergonomic_clones", issue = "132290")]
-#[cfg_attr(not(bootstrap), lang = "use_cloned")]
+#[lang = "use_cloned"]
pub trait UseCloned: Clone {
// Empty.
}
@@ -427,7 +427,7 @@ pub unsafe trait CloneToUninit {
/// read or dropped, because even if it was previously valid, it may have been partially
/// overwritten.
///
- /// The caller may wish to to take care to deallocate the allocation pointed to by `dest`,
+ /// The caller may wish to take care to deallocate the allocation pointed to by `dest`,
/// if applicable, to avoid a memory leak (but this is not a requirement).
///
/// Implementors should avoid leaking values by, upon unwinding, dropping all component values
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index ec7c170..7ca3909 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -1515,19 +1515,6 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
// which guarantees the indexes are always within bounds.
unsafe { (getcount(args, &arg.width), getcount(args, &arg.precision)) };
- #[cfg(bootstrap)]
- let options =
- *FormattingOptions { flags: flags::ALWAYS_SET | arg.flags << 21, width: 0, precision: 0 }
- .align(match arg.align {
- rt::Alignment::Left => Some(Alignment::Left),
- rt::Alignment::Right => Some(Alignment::Right),
- rt::Alignment::Center => Some(Alignment::Center),
- rt::Alignment::Unknown => None,
- })
- .fill(arg.fill)
- .width(width)
- .precision(precision);
- #[cfg(not(bootstrap))]
let options = FormattingOptions { flags: arg.flags, width, precision };
// Extract the correct argument
@@ -1544,21 +1531,6 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
unsafe { value.fmt(fmt) }
}
-#[cfg(bootstrap)]
-unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> {
- match *cnt {
- rt::Count::Is(n) => Some(n as u16),
- rt::Count::Implied => None,
- rt::Count::Param(i) => {
- debug_assert!(i < args.len());
- // SAFETY: cnt and args come from the same Arguments,
- // which guarantees this index is always within bounds.
- unsafe { args.get_unchecked(i).as_u16() }
- }
- }
-}
-
-#[cfg(not(bootstrap))]
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> u16 {
match *cnt {
rt::Count::Is(n) => n,
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index 0b04ebc..0459674 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -11,10 +11,6 @@
#[derive(Copy, Clone)]
pub struct Placeholder {
pub position: usize,
- #[cfg(bootstrap)]
- pub fill: char,
- #[cfg(bootstrap)]
- pub align: Alignment,
pub flags: u32,
pub precision: Count,
pub width: Count,
@@ -23,38 +19,17 @@ pub struct Placeholder {
#[cfg(bootstrap)]
impl Placeholder {
#[inline]
- pub const fn new(
- position: usize,
- fill: char,
- align: Alignment,
- flags: u32,
- precision: Count,
- width: Count,
- ) -> Self {
- Self { position, fill, align, flags, precision, width }
+ pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
+ Self { position, flags, precision, width }
}
}
-#[cfg(bootstrap)]
-#[lang = "format_alignment"]
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub enum Alignment {
- Left,
- Right,
- Center,
- Unknown,
-}
-
/// Used by [width](https://doc.rust-lang.org/std/fmt/#width)
/// and [precision](https://doc.rust-lang.org/std/fmt/#precision) specifiers.
#[lang = "format_count"]
#[derive(Copy, Clone)]
pub enum Count {
/// Specified with a literal number, stores the value
- #[cfg(bootstrap)]
- Is(usize),
- /// Specified with a literal number, stores the value
- #[cfg(not(bootstrap))]
Is(u16),
/// Specified using `$` and `*` syntaxes, stores the index into `args`
Param(usize),
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index f81a6ca..ad33e2e 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2304,20 +2304,8 @@ pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_nounwind]
-#[cfg(not(bootstrap))]
pub fn round_ties_even_f16(x: f16) -> f16;
-/// To be removed on next bootstrap bump.
-#[cfg(bootstrap)]
-pub fn round_ties_even_f16(x: f16) -> f16 {
- #[rustc_intrinsic]
- #[rustc_nounwind]
- unsafe fn rintf16(x: f16) -> f16;
-
- // SAFETY: this intrinsic isn't actually unsafe
- unsafe { rintf16(x) }
-}
-
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
/// least significant digit.
///
@@ -2325,20 +2313,8 @@ pub fn round_ties_even_f16(x: f16) -> f16 {
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_nounwind]
-#[cfg(not(bootstrap))]
pub fn round_ties_even_f32(x: f32) -> f32;
-/// To be removed on next bootstrap bump.
-#[cfg(bootstrap)]
-pub fn round_ties_even_f32(x: f32) -> f32 {
- #[rustc_intrinsic]
- #[rustc_nounwind]
- unsafe fn rintf32(x: f32) -> f32;
-
- // SAFETY: this intrinsic isn't actually unsafe
- unsafe { rintf32(x) }
-}
-
/// Provided for compatibility with stdarch. DO NOT USE.
#[inline(always)]
pub unsafe fn rintf32(x: f32) -> f32 {
@@ -2352,20 +2328,8 @@ pub unsafe fn rintf32(x: f32) -> f32 {
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_nounwind]
-#[cfg(not(bootstrap))]
pub fn round_ties_even_f64(x: f64) -> f64;
-/// To be removed on next bootstrap bump.
-#[cfg(bootstrap)]
-pub fn round_ties_even_f64(x: f64) -> f64 {
- #[rustc_intrinsic]
- #[rustc_nounwind]
- unsafe fn rintf64(x: f64) -> f64;
-
- // SAFETY: this intrinsic isn't actually unsafe
- unsafe { rintf64(x) }
-}
-
/// Provided for compatibility with stdarch. DO NOT USE.
#[inline(always)]
pub unsafe fn rintf64(x: f64) -> f64 {
@@ -2379,20 +2343,8 @@ pub unsafe fn rintf64(x: f64) -> f64 {
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_nounwind]
-#[cfg(not(bootstrap))]
pub fn round_ties_even_f128(x: f128) -> f128;
-/// To be removed on next bootstrap bump.
-#[cfg(bootstrap)]
-pub fn round_ties_even_f128(x: f128) -> f128 {
- #[rustc_intrinsic]
- #[rustc_nounwind]
- unsafe fn rintf128(x: f128) -> f128;
-
- // SAFETY: this intrinsic isn't actually unsafe
- unsafe { rintf128(x) }
-}
-
/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
///
/// The stabilized version of this intrinsic is
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index ae6e1a7..9ac6ee8 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -4,7 +4,7 @@
/// Inserts an element into a vector, returning the updated vector.
///
-/// `T` must be a vector with element type `U`.
+/// `T` must be a vector with element type `U`, and `idx` must be `const`.
///
/// # Safety
///
@@ -15,14 +15,47 @@
/// Extracts an element from a vector.
///
+/// `T` must be a vector with element type `U`, and `idx` must be `const`.
+///
+/// # Safety
+///
+/// `idx` must be const and in-bounds of the vector.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
+
+/// Inserts an element into a vector, returning the updated vector.
+///
/// `T` must be a vector with element type `U`.
///
+/// If the index is `const`, [`simd_insert`] may emit better assembly.
+///
/// # Safety
///
/// `idx` must be in-bounds of the vector.
-#[rustc_intrinsic]
#[rustc_nounwind]
-pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub unsafe fn simd_insert_dyn<T, U>(mut x: T, idx: u32, val: U) -> T {
+ // SAFETY: `idx` must be in-bounds
+ unsafe { (&raw mut x).cast::<U>().add(idx as usize).write(val) }
+ x
+}
+
+/// Extracts an element from a vector.
+///
+/// `T` must be a vector with element type `U`.
+///
+/// If the index is `const`, [`simd_extract`] may emit better assembly.
+///
+/// # Safety
+///
+/// `idx` must be in-bounds of the vector.
+#[rustc_nounwind]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub unsafe fn simd_extract_dyn<T, U>(x: T, idx: u32) -> U {
+ // SAFETY: `idx` must be in-bounds
+ unsafe { (&raw const x).cast::<U>().add(idx as usize).read() }
+}
/// Adds two simd vectors elementwise.
///
diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs
index f9c388e..bd093e2 100644
--- a/library/core/src/iter/adapters/enumerate.rs
+++ b/library/core/src/iter/adapters/enumerate.rs
@@ -36,7 +36,7 @@ impl<I> Iterator for Enumerate<I>
///
/// The method does no guarding against overflows, so enumerating more than
/// `usize::MAX` elements either produces the wrong result or panics. If
- /// debug assertions are enabled, a panic is guaranteed.
+ /// overflow checks are enabled, a panic is guaranteed.
///
/// # Panics
///
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 3bbb52f..d9534a4 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -199,7 +199,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
///
/// The method does no guarding against overflows, so counting elements of
/// an iterator with more than [`usize::MAX`] elements either produces the
- /// wrong result or panics. If debug assertions are enabled, a panic is
+ /// wrong result or panics. If overflow checks are enabled, a panic is
/// guaranteed.
///
/// # Panics
@@ -931,7 +931,7 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
///
/// The method does no guarding against overflows, so enumerating more than
/// [`usize::MAX`] elements either produces the wrong result or panics. If
- /// debug assertions are enabled, a panic is guaranteed.
+ /// overflow checks are enabled, a panic is guaranteed.
///
/// # Panics
///
@@ -2964,7 +2964,7 @@ fn check<I, V, R>(
///
/// The method does no guarding against overflows, so if there are more
/// than [`usize::MAX`] non-matching elements, it either produces the wrong
- /// result or panics. If debug assertions are enabled, a panic is
+ /// result or panics. If overflow checks are enabled, a panic is
/// guaranteed.
///
/// # Panics
@@ -3516,7 +3516,7 @@ fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
/// # Panics
///
/// When calling `sum()` and a primitive integer type is being returned, this
- /// method will panic if the computation overflows and debug assertions are
+ /// method will panic if the computation overflows and overflow checks are
/// enabled.
///
/// # Examples
@@ -3550,7 +3550,7 @@ fn sum<S>(self) -> S
/// # Panics
///
/// When calling `product()` and a primitive integer type is being returned,
- /// method will panic if the computation overflows and debug assertions are
+ /// method will panic if the computation overflows and overflow checks are
/// enabled.
///
/// # Examples
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 5f200b31..330b409 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -237,9 +237,10 @@ macro_rules! assert_ne {
/// ```
#[unstable(feature = "cfg_match", issue = "115585")]
#[rustc_diagnostic_item = "cfg_match"]
+#[rustc_macro_transparency = "semitransparent"]
pub macro cfg_match {
({ $($tt:tt)* }) => {{
- cfg_match! { $($tt)* }
+ $crate::cfg_match! { $($tt)* }
}},
(_ => { $($output:tt)* }) => {
$($output)*
@@ -249,10 +250,10 @@ macro_rules! assert_ne {
$($( $rest:tt )+)?
) => {
#[cfg($cfg)]
- cfg_match! { _ => $output }
+ $crate::cfg_match! { _ => $output }
$(
#[cfg(not($cfg))]
- cfg_match! { $($rest)+ }
+ $crate::cfg_match! { $($rest)+ }
)?
},
}
@@ -1753,7 +1754,6 @@ macro_rules! trace_macros {
reason = "`type_alias_impl_trait` has open design concerns"
)]
#[rustc_builtin_macro]
- #[cfg(not(bootstrap))]
pub macro define_opaque($($tt:tt)*) {
/* compiler built-in */
}
diff --git a/library/core/src/net/socket_addr.rs b/library/core/src/net/socket_addr.rs
index 21753d00..936f9f6 100644
--- a/library/core/src/net/socket_addr.rs
+++ b/library/core/src/net/socket_addr.rs
@@ -210,7 +210,7 @@ pub const fn ip(&self) -> IpAddr {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_ip(&mut self, new_ip: IpAddr) {
// `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
match (self, new_ip) {
@@ -254,7 +254,7 @@ pub const fn port(&self) -> u16 {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_port(&mut self, new_port: u16) {
match *self {
SocketAddr::V4(ref mut a) => a.set_port(new_port),
@@ -360,7 +360,7 @@ pub const fn ip(&self) -> &Ipv4Addr {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_ip(&mut self, new_ip: Ipv4Addr) {
self.ip = new_ip;
}
@@ -396,7 +396,7 @@ pub const fn port(&self) -> u16 {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_port(&mut self, new_port: u16) {
self.port = new_port;
}
@@ -458,7 +458,7 @@ pub const fn ip(&self) -> &Ipv6Addr {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_ip(&mut self, new_ip: Ipv6Addr) {
self.ip = new_ip;
}
@@ -494,7 +494,7 @@ pub const fn port(&self) -> u16 {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_port(&mut self, new_port: u16) {
self.port = new_port;
}
@@ -542,7 +542,7 @@ pub const fn flowinfo(&self) -> u32 {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_flowinfo(&mut self, new_flowinfo: u32) {
self.flowinfo = new_flowinfo;
}
@@ -585,7 +585,7 @@ pub const fn scope_id(&self) -> u32 {
/// ```
#[inline]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_sockaddr_setters", since = "1.87.0")]
pub const fn set_scope_id(&mut self, new_scope_id: u32) {
self.scope_id = new_scope_id;
}
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index a72ca4b..de0d55e 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -244,8 +244,8 @@ pub const fn isolate_least_significant_one(self) -> Self {
///
#[doc = concat!("assert_eq!(n.cast_unsigned(), ", stringify!($UnsignedT), "::MAX);")]
/// ```
- #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "integer_sign_cast", since = "1.87.0")]
+ #[rustc_const_stable(feature = "integer_sign_cast", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
@@ -1355,8 +1355,8 @@ pub const fn strict_shl(self, rhs: u32) -> Self {
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
/// ```
- #[stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "unbounded_shifts", since = "1.87.0")]
+ #[rustc_const_stable(feature = "unbounded_shifts", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -1478,8 +1478,8 @@ pub const fn strict_shr(self, rhs: u32) -> Self {
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")]
/// ```
- #[stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "unbounded_shifts", since = "1.87.0")]
+ #[rustc_const_stable(feature = "unbounded_shifts", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 151e128..348457e 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -99,8 +99,8 @@ macro_rules! i8_xe_bytes_doc {
**Note**: This function is meaningless on `i8`. Byte order does not exist as a
concept for byte-sized integers. This function is only provided in symmetry
-with larger integer types. You can cast from and to `u8` using `as i8` and `as
-u8`.
+with larger integer types. You can cast from and to `u8` using
+[`cast_signed`](u8::cast_signed) and [`cast_unsigned`](Self::cast_unsigned).
"
};
@@ -169,8 +169,8 @@ pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
/// ```
- #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "num_midpoint_signed", since = "1.87.0")]
+ #[rustc_const_stable(feature = "num_midpoint_signed", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -221,8 +221,8 @@ pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
/// ```
- #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "num_midpoint_signed", since = "1.87.0")]
+ #[rustc_const_stable(feature = "num_midpoint_signed", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 7585ec1..1b79112 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1704,8 +1704,8 @@ pub const fn isqrt(self) -> Self {
///
#[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1", stringify!($Sint), ").unwrap());")]
/// ```
- #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "integer_sign_cast", since = "1.87.0")]
+ #[rustc_const_stable(feature = "integer_sign_cast", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
@@ -2143,8 +2143,8 @@ pub const fn wrapping_neg(self) -> Self {
///
#[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<", stringify!($Uint), ">::MAX);")]
/// ```
- #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "integer_sign_cast", since = "1.87.0")]
+ #[rustc_const_stable(feature = "integer_sign_cast", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 5868927..1b2acdc 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -273,8 +273,8 @@ pub const fn isolate_least_significant_one(self) -> Self {
///
#[doc = concat!("assert_eq!(n.cast_signed(), -1", stringify!($SignedT), ");")]
/// ```
- #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "integer_sign_cast", since = "1.87.0")]
+ #[rustc_const_stable(feature = "integer_sign_cast", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
@@ -1616,8 +1616,8 @@ pub const fn strict_shl(self, rhs: u32) -> Self {
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
/// ```
- #[stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "unbounded_shifts", since = "1.87.0")]
+ #[rustc_const_stable(feature = "unbounded_shifts", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -1737,8 +1737,8 @@ pub const fn strict_shr(self, rhs: u32) -> Self {
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
/// ```
- #[stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "unbounded_shifts", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "unbounded_shifts", since = "1.87.0")]
+ #[rustc_const_stable(feature = "unbounded_shifts", since = "1.87.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -3331,8 +3331,8 @@ pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
#[doc = concat!("assert!(0_", stringify!($SelfT), ".is_multiple_of(0));")]
#[doc = concat!("assert!(!6_", stringify!($SelfT), ".is_multiple_of(0));")]
/// ```
- #[stable(feature = "unsigned_is_multiple_of", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "unsigned_is_multiple_of", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "unsigned_is_multiple_of", since = "1.87.0")]
+ #[rustc_const_stable(feature = "unsigned_is_multiple_of", since = "1.87.0")]
#[must_use]
#[inline]
#[rustc_inherit_overflow_checks]
diff --git a/library/core/src/pat.rs b/library/core/src/pat.rs
index f882609..91d015b 100644
--- a/library/core/src/pat.rs
+++ b/library/core/src/pat.rs
@@ -25,15 +25,15 @@ macro_rules! pattern_type {
)]
pub trait RangePattern {
/// Trait version of the inherent `MIN` assoc const.
- #[cfg_attr(not(bootstrap), lang = "RangeMin")]
+ #[lang = "RangeMin"]
const MIN: Self;
/// Trait version of the inherent `MIN` assoc const.
- #[cfg_attr(not(bootstrap), lang = "RangeMax")]
+ #[lang = "RangeMax"]
const MAX: Self;
/// A compile-time helper to subtract 1 for exclusive ranges.
- #[cfg_attr(not(bootstrap), lang = "RangeSub")]
+ #[lang = "RangeSub"]
#[track_caller]
fn sub_one(self) -> Self;
}
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index bc097bf1..2ef1bbf 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1943,7 +1943,7 @@ unsafe impl<T: ?Sized> PinCoerceUnsized for *mut T {}
#[stable(feature = "pin_macro", since = "1.68.0")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(unsafe_pin_internals)]
-#[cfg_attr(not(bootstrap), rustc_macro_edition_2021)]
+#[rustc_macro_edition_2021]
pub macro pin($value:expr $(,)?) {
// This is `Pin::new_unchecked(&mut { $value })`, so, for starters, let's
// review such a hypothetical macro (that any user-code could define):
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index c5975c0..8f1b527 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -117,5 +117,4 @@
issue = "63063",
reason = "`type_alias_impl_trait` has open design concerns"
)]
-#[cfg(not(bootstrap))]
pub use crate::macros::builtin::define_opaque;
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 71a84af..0854e31 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -764,8 +764,8 @@ pub fn mask(self, mask: usize) -> *const T {
/// // This would be incorrect, as the pointers are not correctly ordered:
/// // ptr1.offset_from_unsigned(ptr2)
/// ```
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
@@ -809,8 +809,8 @@ const fn runtime_ptr_ge(this: *const (), origin: *const ()) -> bool {
///
/// For non-`Sized` pointees this operation considers only the data pointers,
/// ignoring the metadata.
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *const U) -> usize {
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index ea53da7..2357ba2 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -398,6 +398,7 @@
use crate::intrinsics::const_eval_select;
use crate::marker::FnPtr;
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
+use crate::num::NonZero;
use crate::{fmt, hash, intrinsics, ub_checks};
mod alignment;
@@ -1094,51 +1095,25 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
// are pointers inside `T` we will copy them in one go rather than trying to copy a part
// of a pointer (which would not work).
// SAFETY: Same preconditions as this function
- unsafe { swap_nonoverlapping_simple_untyped(x, y, count) }
+ unsafe { swap_nonoverlapping_const(x, y, count) }
} else {
- macro_rules! attempt_swap_as_chunks {
- ($ChunkTy:ty) => {
- if align_of::<T>() >= align_of::<$ChunkTy>()
- && size_of::<T>() % size_of::<$ChunkTy>() == 0
- {
- let x: *mut $ChunkTy = x.cast();
- let y: *mut $ChunkTy = y.cast();
- let count = count * (size_of::<T>() / size_of::<$ChunkTy>());
- // SAFETY: these are the same bytes that the caller promised were
- // ok, just typed as `MaybeUninit<ChunkTy>`s instead of as `T`s.
- // The `if` condition above ensures that we're not violating
- // alignment requirements, and that the division is exact so
- // that we don't lose any bytes off the end.
- return unsafe { swap_nonoverlapping_simple_untyped(x, y, count) };
- }
- };
+ // Going though a slice here helps codegen know the size fits in `isize`
+ let slice = slice_from_raw_parts_mut(x, count);
+ // SAFETY: This is all readable from the pointer, meaning it's one
+ // allocated object, and thus cannot be more than isize::MAX bytes.
+ let bytes = unsafe { mem::size_of_val_raw::<[T]>(slice) };
+ if let Some(bytes) = NonZero::new(bytes) {
+ // SAFETY: These are the same ranges, just expressed in a different
+ // type, so they're still non-overlapping.
+ unsafe { swap_nonoverlapping_bytes(x.cast(), y.cast(), bytes) };
}
-
- // Split up the slice into small power-of-two-sized chunks that LLVM is able
- // to vectorize (unless it's a special type with more-than-pointer alignment,
- // because we don't want to pessimize things like slices of SIMD vectors.)
- if align_of::<T>() <= size_of::<usize>()
- && (!size_of::<T>().is_power_of_two()
- || size_of::<T>() > size_of::<usize>() * 2)
- {
- attempt_swap_as_chunks!(usize);
- attempt_swap_as_chunks!(u8);
- }
-
- // SAFETY: Same preconditions as this function
- unsafe { swap_nonoverlapping_simple_untyped(x, y, count) }
}
)
}
/// Same behavior and safety conditions as [`swap_nonoverlapping`]
-///
-/// LLVM can vectorize this (at least it can for the power-of-two-sized types
-/// `swap_nonoverlapping` tries to use) so no need to manually SIMD it.
#[inline]
-const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, count: usize) {
- let x = x.cast::<MaybeUninit<T>>();
- let y = y.cast::<MaybeUninit<T>>();
+const unsafe fn swap_nonoverlapping_const<T>(x: *mut T, y: *mut T, count: usize) {
let mut i = 0;
while i < count {
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
@@ -1147,26 +1122,91 @@ macro_rules! attempt_swap_as_chunks {
// and it's distinct from `x` since the ranges are non-overlapping
let y = unsafe { y.add(i) };
- // If we end up here, it's because we're using a simple type -- like
- // a small power-of-two-sized thing -- or a special type with particularly
- // large alignment, particularly SIMD types.
- // Thus, we're fine just reading-and-writing it, as either it's small
- // and that works well anyway or it's special and the type's author
- // presumably wanted things to be done in the larger chunk.
-
// SAFETY: we're only ever given pointers that are valid to read/write,
// including being aligned, and nothing here panics so it's drop-safe.
unsafe {
- let a: MaybeUninit<T> = read(x);
- let b: MaybeUninit<T> = read(y);
- write(x, b);
- write(y, a);
+ // Note that it's critical that these use `copy_nonoverlapping`,
+ // rather than `read`/`write`, to avoid #134713 if T has padding.
+ let mut temp = MaybeUninit::<T>::uninit();
+ copy_nonoverlapping(x, temp.as_mut_ptr(), 1);
+ copy_nonoverlapping(y, x, 1);
+ copy_nonoverlapping(temp.as_ptr(), y, 1);
}
i += 1;
}
}
+// Don't let MIR inline this, because we really want it to keep its noalias metadata
+#[rustc_no_mir_inline]
+#[inline]
+fn swap_chunk<const N: usize>(x: &mut MaybeUninit<[u8; N]>, y: &mut MaybeUninit<[u8; N]>) {
+ let a = *x;
+ let b = *y;
+ *x = b;
+ *y = a;
+}
+
+#[inline]
+unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, bytes: NonZero<usize>) {
+ // Same as `swap_nonoverlapping::<[u8; N]>`.
+ unsafe fn swap_nonoverlapping_chunks<const N: usize>(
+ x: *mut MaybeUninit<[u8; N]>,
+ y: *mut MaybeUninit<[u8; N]>,
+ chunks: NonZero<usize>,
+ ) {
+ let chunks = chunks.get();
+ for i in 0..chunks {
+ // SAFETY: i is in [0, chunks) so the adds and dereferences are in-bounds.
+ unsafe { swap_chunk(&mut *x.add(i), &mut *y.add(i)) };
+ }
+ }
+
+ // Same as `swap_nonoverlapping_bytes`, but accepts at most 1+2+4=7 bytes
+ #[inline]
+ unsafe fn swap_nonoverlapping_short(x: *mut u8, y: *mut u8, bytes: NonZero<usize>) {
+ // Tail handling for auto-vectorized code sometimes has element-at-a-time behaviour,
+ // see <https://github.com/rust-lang/rust/issues/134946>.
+ // By swapping as different sizes, rather than as a loop over bytes,
+ // we make sure not to end up with, say, seven byte-at-a-time copies.
+
+ let bytes = bytes.get();
+ let mut i = 0;
+ macro_rules! swap_prefix {
+ ($($n:literal)+) => {$(
+ if (bytes & $n) != 0 {
+ // SAFETY: `i` can only have the same bits set as those in bytes,
+ // so these `add`s are in-bounds of `bytes`. But the bit for
+ // `$n` hasn't been set yet, so the `$n` bytes that `swap_chunk`
+ // will read and write are within the usable range.
+ unsafe { swap_chunk::<$n>(&mut*x.add(i).cast(), &mut*y.add(i).cast()) };
+ i |= $n;
+ }
+ )+};
+ }
+ swap_prefix!(4 2 1);
+ debug_assert_eq!(i, bytes);
+ }
+
+ const CHUNK_SIZE: usize = size_of::<*const ()>();
+ let bytes = bytes.get();
+
+ let chunks = bytes / CHUNK_SIZE;
+ let tail = bytes % CHUNK_SIZE;
+ if let Some(chunks) = NonZero::new(chunks) {
+ // SAFETY: this is bytes/CHUNK_SIZE*CHUNK_SIZE bytes, which is <= bytes,
+ // so it's within the range of our non-overlapping bytes.
+ unsafe { swap_nonoverlapping_chunks::<CHUNK_SIZE>(x.cast(), y.cast(), chunks) };
+ }
+ if let Some(tail) = NonZero::new(tail) {
+ const { assert!(CHUNK_SIZE <= 8) };
+ let delta = chunks * CHUNK_SIZE;
+ // SAFETY: the tail length is below CHUNK SIZE because of the remainder,
+ // and CHUNK_SIZE is at most 8 by the const assert, so tail <= 7
+ unsafe { swap_nonoverlapping_short(x.add(delta), y.add(delta), tail) };
+ }
+}
+
/// Moves `src` into the pointed `dst`, returning the previous `dst` value.
///
/// Neither value is dropped.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 9e62beb..e297749 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -937,8 +937,8 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
///
/// // This would be incorrect, as the pointers are not correctly ordered:
/// // ptr1.offset_from(ptr2)
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
@@ -959,8 +959,8 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
///
/// For non-`Sized` pointees this operation considers only the data pointers,
/// ignoring the metadata.
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *mut U) -> usize {
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index e019aaf..68b8f0c 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -900,8 +900,8 @@ pub const fn cast<U>(self) -> NonNull<U> {
/// ```
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
pub const unsafe fn offset_from_unsigned(self, subtracted: NonNull<T>) -> usize
where
T: Sized,
@@ -922,8 +922,8 @@ pub const fn cast<U>(self) -> NonNull<U> {
/// ignoring the metadata.
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: NonNull<U>) -> usize {
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
unsafe { self.as_ptr().byte_offset_from_unsigned(origin.as_ptr()) }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index c7e8d5f..b906899 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3721,7 +3721,7 @@ pub fn clone_from_slice(&mut self, src: &[T])
#[doc(alias = "memcpy")]
#[inline]
#[stable(feature = "copy_from_slice", since = "1.9.0")]
- #[rustc_const_stable(feature = "const_copy_from_slice", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_copy_from_slice", since = "1.87.0")]
#[track_caller]
pub const fn copy_from_slice(&mut self, src: &[T])
where
@@ -4331,7 +4331,7 @@ pub fn partition_point<P>(&self, mut pred: P) -> usize
/// ```
#[inline]
#[must_use = "method does not modify the slice if the range is out of bounds"]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
pub fn split_off<'a, R: OneSidedRange<usize>>(
self: &mut &'a Self,
range: R,
@@ -4397,7 +4397,7 @@ pub fn split_off<'a, R: OneSidedRange<usize>>(
/// ```
#[inline]
#[must_use = "method does not modify the slice if the range is out of bounds"]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
pub fn split_off_mut<'a, R: OneSidedRange<usize>>(
self: &mut &'a mut Self,
range: R,
@@ -4434,7 +4434,7 @@ pub fn split_off_mut<'a, R: OneSidedRange<usize>>(
/// assert_eq!(first, &'a');
/// ```
#[inline]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
#[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
// FIXME(const-hack): Use `?` when available in const instead of `let-else`.
@@ -4459,7 +4459,7 @@ pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
/// assert_eq!(first, &'d');
/// ```
#[inline]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
#[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
// FIXME(const-hack): Use `mem::take` and `?` when available in const.
@@ -4484,7 +4484,7 @@ pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut
/// assert_eq!(last, &'c');
/// ```
#[inline]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
#[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
// FIXME(const-hack): Use `?` when available in const instead of `let-else`.
@@ -4509,7 +4509,7 @@ pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
/// assert_eq!(last, &'d');
/// ```
#[inline]
- #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "slice_take", since = "1.87.0")]
#[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
pub const fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
// FIXME(const-hack): Use `mem::take` and `?` when available in const.
@@ -4841,7 +4841,7 @@ pub fn align_to_uninit_mut<U>(&mut self) -> (&mut Self, &mut [MaybeUninit<U>], &
/// assert!(empty_slice_of_arrays.as_flattened().is_empty());
/// ```
#[stable(feature = "slice_flatten", since = "1.80.0")]
- #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_slice_flatten", since = "1.87.0")]
pub const fn as_flattened(&self) -> &[T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
@@ -4878,7 +4878,7 @@ pub const fn as_flattened(&self) -> &[T] {
/// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
/// ```
#[stable(feature = "slice_flatten", since = "1.80.0")]
- #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "const_slice_flatten", since = "1.87.0")]
pub const fn as_flattened_mut(&mut self) -> &mut [T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
index 1276d90..37854a4 100644
--- a/library/core/src/str/converts.rs
+++ b/library/core/src/str/converts.rs
@@ -126,7 +126,7 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
/// See the docs for [`Utf8Error`] for more details on the kinds of
/// errors that can be returned.
#[stable(feature = "str_mut_extras", since = "1.20.0")]
-#[rustc_const_stable(feature = "const_str_from_utf8", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_str_from_utf8", since = "1.87.0")]
#[rustc_diagnostic_item = "str_from_utf8_mut"]
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
// FIXME(const-hack): This should use `?` again, once it's `const`
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 5cc08f8a..79b4953 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -230,8 +230,8 @@ pub const fn is_empty(&self) -> bool {
///
/// assert_eq!("💖", sparkle_heart);
/// ```
- #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "inherent_str_constructors", since = "1.87.0")]
+ #[rustc_const_stable(feature = "inherent_str_constructors", since = "1.87.0")]
#[rustc_diagnostic_item = "str_inherent_from_utf8"]
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
converts::from_utf8(v)
@@ -263,8 +263,8 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
/// ```
/// See the docs for [`Utf8Error`] for more details on the kinds of
/// errors that can be returned.
- #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "const_str_from_utf8", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "inherent_str_constructors", since = "1.87.0")]
+ #[rustc_const_stable(feature = "const_str_from_utf8", since = "1.87.0")]
#[rustc_diagnostic_item = "str_inherent_from_utf8_mut"]
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
converts::from_utf8_mut(v)
@@ -295,8 +295,8 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
/// ```
#[inline]
#[must_use]
- #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "inherent_str_constructors", since = "1.87.0")]
+ #[rustc_const_stable(feature = "inherent_str_constructors", since = "1.87.0")]
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked"]
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
// SAFETY: converts::from_utf8_unchecked has the same safety requirements as this function.
@@ -320,8 +320,8 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
/// ```
#[inline]
#[must_use]
- #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
- #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "inherent_str_constructors", since = "1.87.0")]
+ #[rustc_const_stable(feature = "inherent_str_constructors", since = "1.87.0")]
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked_mut"]
pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
// SAFETY: converts::from_utf8_unchecked_mut has the same safety requirements as this function.
diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs
index 3174c91..bfbfa8d 100644
--- a/library/coretests/tests/pin_macro.rs
+++ b/library/coretests/tests/pin_macro.rs
@@ -38,7 +38,6 @@ fn rust_2024_expr() {
}
#[test]
-#[cfg(not(bootstrap))]
fn temp_lifetime() {
// Check that temporary lifetimes work as in Rust 2021.
// Regression test for https://github.com/rust-lang/rust/issues/138596
diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs
index 6091926..cc5f794 100644
--- a/library/coretests/tests/ptr.rs
+++ b/library/coretests/tests/ptr.rs
@@ -984,3 +984,39 @@ fn test_ptr_metadata_in_const() {
assert_eq!(SLICE_META, 3);
assert_eq!(DYN_META.size_of(), 42);
}
+
+// See <https://github.com/rust-lang/rust/issues/134713>
+const fn ptr_swap_nonoverlapping_is_untyped_inner() {
+ #[repr(C)]
+ struct HasPadding(usize, u8);
+
+ let buf1: [usize; 2] = [1000, 2000];
+ let buf2: [usize; 2] = [3000, 4000];
+
+ // HasPadding and [usize; 2] have the same size and alignment,
+ // so swap_nonoverlapping should treat them the same
+ assert!(size_of::<HasPadding>() == size_of::<[usize; 2]>());
+ assert!(align_of::<HasPadding>() == align_of::<[usize; 2]>());
+
+ let mut b1 = buf1;
+ let mut b2 = buf2;
+ // Safety: b1 and b2 are distinct local variables,
+ // with the same size and alignment as HasPadding.
+ unsafe {
+ std::ptr::swap_nonoverlapping(
+ b1.as_mut_ptr().cast::<HasPadding>(),
+ b2.as_mut_ptr().cast::<HasPadding>(),
+ 1,
+ );
+ }
+ assert!(b1[0] == buf2[0]);
+ assert!(b1[1] == buf2[1]);
+ assert!(b2[0] == buf1[0]);
+ assert!(b2[1] == buf1[1]);
+}
+
+#[test]
+fn test_ptr_swap_nonoverlapping_is_untyped() {
+ ptr_swap_nonoverlapping_is_untyped_inner();
+ const { ptr_swap_nonoverlapping_is_untyped_inner() };
+}
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index e5c1d6b..50bd933 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -79,11 +79,11 @@
unsafe extern "C" {
/// Handler in std called when a panic object is dropped outside of
/// `catch_unwind`.
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_drop_panic() -> !;
/// Handler in std called when a foreign exception is caught.
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_foreign_exception() -> !;
}
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 52cc8fb..1b5c221 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -9,7 +9,6 @@
#![deny(unsafe_code)]
// proc_macros anyway don't work on wasm hosts so while both sides of this bridge can
// be built with different versions of rustc, the wasm ABI changes don't really matter.
-#![cfg_attr(bootstrap, allow(unknown_lints))]
#![allow(wasm_c_abi)]
use std::hash::Hash;
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 176da60..6b70ff7 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.152" }
+compiler_builtins = { version = "=0.1.153" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index 5d2a304..75971ac 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -348,7 +348,7 @@ fn default_alloc_error_hook(layout: Layout) {
unsafe extern "Rust" {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
static __rust_alloc_error_handler_should_panic: u8;
}
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index 3e641ac..3683485 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -432,7 +432,7 @@ mod helper {
use super::*;
pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe;
- #[cfg_attr(not(bootstrap), define_opaque(LazyResolve))]
+ #[define_opaque(LazyResolve)]
pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve {
move || {
// Use the global backtrace lock to synchronize this as it's a
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 2487f5a..0eef2bd 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -683,7 +683,7 @@ pub fn drain(&mut self) -> Drain<'_, K, V> {
/// ```
#[inline]
#[rustc_lint_query_instability]
- #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "hash_extract_if", since = "1.87.0")]
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
@@ -1677,7 +1677,7 @@ pub(super) fn iter(&self) -> Iter<'_, K, V> {
/// ]);
/// let iter = map.extract_if(|_k, v| *v % 2 == 0);
/// ```
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ExtractIf<'a, K, V, F>
where
@@ -2294,7 +2294,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<K, V, F> Iterator for ExtractIf<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
@@ -2311,10 +2311,10 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index a547a99..7be0005 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -308,7 +308,7 @@ pub fn drain(&mut self) -> Drain<'_, T> {
/// ```
#[inline]
#[rustc_lint_query_instability]
- #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "hash_extract_if", since = "1.87.0")]
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F>
where
F: FnMut(&T) -> bool,
@@ -1390,7 +1390,7 @@ pub struct Drain<'a, K: 'a> {
///
/// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
/// ```
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
pub struct ExtractIf<'a, K, F>
where
F: FnMut(&K) -> bool,
@@ -1673,7 +1673,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<K, F> Iterator for ExtractIf<'_, K, F>
where
F: FnMut(&K) -> bool,
@@ -1690,10 +1690,10 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<K, F> FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {}
-#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "hash_extract_if", since = "1.87.0")]
impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F>
where
F: FnMut(&K) -> bool,
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 860ec3a..d34e3ca 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -201,5 +201,5 @@
#[doc(inline)]
pub use self::os_str::{OsStr, OsString};
-#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "os_str_display", since = "1.87.0")]
pub mod os_str;
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index aa25ff5..ce01175 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -1255,7 +1255,7 @@ pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
/// let s = OsStr::new("Hello, world!");
/// println!("{}", s.display());
/// ```
- #[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "os_str_display", since = "1.87.0")]
#[must_use = "this does not display the `OsStr`; \
it returns an object that can be displayed"]
#[inline]
@@ -1612,19 +1612,19 @@ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
///
/// [`Display`]: fmt::Display
/// [`format!`]: crate::format
-#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "os_str_display", since = "1.87.0")]
pub struct Display<'a> {
os_str: &'a OsStr,
}
-#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "os_str_display", since = "1.87.0")]
impl fmt::Debug for Display<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.os_str, f)
}
}
-#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "os_str_display", since = "1.87.0")]
impl fmt::Display for Display<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.os_str.inner, f)
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 8472f90..2498fb8 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -374,7 +374,7 @@ pub enum ErrorKind {
/// A filename was invalid.
///
/// This error can also occur if a length limit for a name was exceeded.
- #[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "io_error_invalid_filename", since = "1.87.0")]
InvalidFilename,
/// Program argument list too long.
///
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 314cbb4..b6545ea 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -310,7 +310,7 @@
pub use self::error::SimpleMessage;
#[unstable(feature = "io_const_error", issue = "133448")]
pub use self::error::const_error;
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
pub use self::pipe::{PipeReader, PipeWriter, pipe};
#[stable(feature = "is_terminal", since = "1.70.0")]
pub use self::stdio::IsTerminal;
diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs
index cfed9b0..c6b7b49 100644
--- a/library/std/src/io/pipe.rs
+++ b/library/std/src/io/pipe.rs
@@ -67,19 +67,19 @@
/// ```
/// [changes]: io#platform-specific-behavior
/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[inline]
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer)))
}
/// Read end of an anonymous pipe.
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[derive(Debug)]
pub struct PipeReader(pub(crate) AnonPipe);
/// Write end of an anonymous pipe.
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[derive(Debug)]
pub struct PipeWriter(pub(crate) AnonPipe);
@@ -160,7 +160,7 @@ impl PipeReader {
/// # Ok(())
/// # }
/// ```
- #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "anonymous_pipe", since = "1.87.0")]
pub fn try_clone(&self) -> io::Result<Self> {
self.0.try_clone().map(Self)
}
@@ -199,13 +199,13 @@ impl PipeWriter {
/// # Ok(())
/// # }
/// ```
- #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+ #[stable(feature = "anonymous_pipe", since = "1.87.0")]
pub fn try_clone(&self) -> io::Result<Self> {
self.0.try_clone().map(Self)
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl io::Read for &PipeReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
@@ -225,7 +225,7 @@ fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl io::Read for PipeReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
@@ -245,7 +245,7 @@ fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl io::Write for &PipeWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
@@ -263,7 +263,7 @@ fn is_write_vectored(&self) -> bool {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl io::Write for PipeWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index be73e7d..10e1e73 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -505,7 +505,7 @@ fn as_fd(&self) -> BorrowedFd<'_> {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl AsFd for io::PipeReader {
fn as_fd(&self) -> BorrowedFd<'_> {
@@ -513,7 +513,7 @@ fn as_fd(&self) -> BorrowedFd<'_> {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl From<io::PipeReader> for OwnedFd {
fn from(pipe: io::PipeReader) -> Self {
@@ -521,7 +521,7 @@ fn from(pipe: io::PipeReader) -> Self {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl AsFd for io::PipeWriter {
fn as_fd(&self) -> BorrowedFd<'_> {
@@ -529,7 +529,7 @@ fn as_fd(&self) -> BorrowedFd<'_> {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl From<io::PipeWriter> for OwnedFd {
fn from(pipe: io::PipeWriter) -> Self {
@@ -537,7 +537,7 @@ fn from(pipe: io::PipeWriter) -> Self {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl From<OwnedFd> for io::PipeReader {
fn from(owned_fd: OwnedFd) -> Self {
@@ -545,7 +545,7 @@ fn from(owned_fd: OwnedFd) -> Self {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl From<OwnedFd> for io::PipeWriter {
fn from(owned_fd: OwnedFd) -> Self {
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index c800c14..34a6cf1 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -285,7 +285,7 @@ fn as_raw_fd(&self) -> RawFd {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl AsRawFd for io::PipeReader {
fn as_raw_fd(&self) -> RawFd {
@@ -293,7 +293,7 @@ fn as_raw_fd(&self) -> RawFd {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl FromRawFd for io::PipeReader {
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
@@ -301,7 +301,7 @@ unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl IntoRawFd for io::PipeReader {
fn into_raw_fd(self) -> RawFd {
@@ -309,7 +309,7 @@ fn into_raw_fd(self) -> RawFd {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl AsRawFd for io::PipeWriter {
fn as_raw_fd(&self) -> RawFd {
@@ -317,7 +317,7 @@ fn as_raw_fd(&self) -> RawFd {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl FromRawFd for io::PipeWriter {
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
@@ -325,7 +325,7 @@ unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
#[cfg(not(target_os = "trusty"))]
impl IntoRawFd for io::PipeWriter {
fn into_raw_fd(self) -> RawFd {
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 7f21929..4fc04b7 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -661,42 +661,42 @@ fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl AsHandle for io::PipeReader {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.0.as_handle()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<io::PipeReader> for OwnedHandle {
fn from(pipe: io::PipeReader) -> Self {
pipe.into_inner().into_inner()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl AsHandle for io::PipeWriter {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.0.as_handle()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<io::PipeWriter> for OwnedHandle {
fn from(pipe: io::PipeWriter) -> Self {
pipe.into_inner().into_inner()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<OwnedHandle> for io::PipeReader {
fn from(owned_handle: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(owned_handle))
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<OwnedHandle> for io::PipeWriter {
fn from(owned_handle: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(owned_handle))
diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs
index bc3e55c..a3ec744 100644
--- a/library/std/src/os/windows/io/raw.rs
+++ b/library/std/src/os/windows/io/raw.rs
@@ -311,42 +311,42 @@ fn into_raw_socket(self) -> RawSocket {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl AsRawHandle for io::PipeReader {
fn as_raw_handle(&self) -> RawHandle {
self.0.as_raw_handle()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl FromRawHandle for io::PipeReader {
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl IntoRawHandle for io::PipeReader {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl AsRawHandle for io::PipeWriter {
fn as_raw_handle(&self) -> RawHandle {
self.0.as_raw_handle()
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl FromRawHandle for io::PipeWriter {
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl IntoRawHandle for io::PipeWriter {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index b35549c..a395098 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -55,14 +55,14 @@
// hook up these functions, but it is not this day!
#[allow(improper_ctypes)]
unsafe extern "C" {
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static);
}
unsafe extern "Rust" {
/// `PanicPayload` lazily performs allocation only when needed (this avoids
/// allocations when using the "abort" panic runtime).
- #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)]
+ #[rustc_std_internal_symbol]
fn __rust_start_panic(payload: &mut dyn PanicPayload) -> u32;
}
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 4217f65..c15d8c4 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -109,7 +109,6 @@
issue = "63063",
reason = "`type_alias_impl_trait` has open design concerns"
)]
-#[cfg(not(bootstrap))]
pub use core::prelude::v1::define_opaque;
// The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 3b765a9..da51801 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1659,14 +1659,14 @@ fn from(inherit: io::Stderr) -> Stdio {
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<io::PipeWriter> for Stdio {
fn from(pipe: io::PipeWriter) -> Self {
Stdio::from_inner(pipe.into_inner().into())
}
}
-#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "anonymous_pipe", since = "1.87.0")]
impl From<io::PipeReader> for Stdio {
fn from(pipe: io::PipeReader) -> Self {
Stdio::from_inner(pipe.into_inner().into())
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index 9362c76..adb74bb 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -582,7 +582,9 @@ pub fn into_inner(self) -> LockResult<T>
/// Returns a mutable reference to the underlying data.
///
/// Since this call borrows the `Mutex` mutably, no actual locking needs to
- /// take place -- the mutable borrow statically guarantees no locks exist.
+ /// take place -- the mutable borrow statically guarantees no new locks can be acquired
+ /// while this reference exists. Note that this method does not clear any previous abandoned locks
+ /// (e.g., via [`forget()`] on a [`MutexGuard`]).
///
/// # Errors
///
@@ -599,6 +601,8 @@ pub fn into_inner(self) -> LockResult<T>
/// *mutex.get_mut().unwrap() = 10;
/// assert_eq!(*mutex.lock().unwrap(), 10);
/// ```
+ ///
+ /// [`forget()`]: mem::forget
#[stable(feature = "mutex_get_mut", since = "1.6.0")]
pub fn get_mut(&mut self) -> LockResult<&mut T> {
let data = self.data.get_mut();
diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs
index f9d9321..a2abd4f 100644
--- a/library/std/src/sync/poison/rwlock.rs
+++ b/library/std/src/sync/poison/rwlock.rs
@@ -608,7 +608,9 @@ pub fn into_inner(self) -> LockResult<T>
/// Returns a mutable reference to the underlying data.
///
/// Since this call borrows the `RwLock` mutably, no actual locking needs to
- /// take place -- the mutable borrow statically guarantees no locks exist.
+ /// take place -- the mutable borrow statically guarantees no new locks can be acquired
+ /// while this reference exists. Note that this method does not clear any previously abandoned locks
+ /// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
///
/// # Errors
///
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index 1c53472..6547ed9 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -350,3 +350,46 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
pub(crate) fn is_absolute(path: &Path) -> bool {
path.has_root() && path.prefix().is_some()
}
+
+/// Test that the path is absolute, fully qualified and unchanged when processed by the Windows API.
+///
+/// For example:
+///
+/// - `C:\path\to\file` will return true.
+/// - `C:\path\to\nul` returns false because the Windows API will convert it to \\.\NUL
+/// - `C:\path\to\..\file` returns false because it will be resolved to `C:\path\file`.
+///
+/// This is a useful property because it means the path can be converted from and to and verbatim
+/// path just by changing the prefix.
+pub(crate) fn is_absolute_exact(path: &[u16]) -> bool {
+ // This is implemented by checking that passing the path through
+ // GetFullPathNameW does not change the path in any way.
+
+ // Windows paths are limited to i16::MAX length
+ // though the API here accepts a u32 for the length.
+ if path.is_empty() || path.len() > u32::MAX as usize || path.last() != Some(&0) {
+ return false;
+ }
+ // The path returned by `GetFullPathNameW` must be the same length as the
+ // given path, otherwise they're not equal.
+ let buffer_len = path.len();
+ let mut new_path = Vec::with_capacity(buffer_len);
+ let result = unsafe {
+ c::GetFullPathNameW(
+ path.as_ptr(),
+ new_path.capacity() as u32,
+ new_path.as_mut_ptr(),
+ crate::ptr::null_mut(),
+ )
+ };
+ // Note: if non-zero, the returned result is the length of the buffer without the null termination
+ if result == 0 || result as usize != buffer_len - 1 {
+ false
+ } else {
+ // SAFETY: `GetFullPathNameW` initialized `result` bytes and does not exceed `nBufferLength - 1` (capacity).
+ unsafe {
+ new_path.set_len((result as usize) + 1);
+ }
+ path == &new_path
+ }
+}
diff --git a/library/std/src/sys/path/windows/tests.rs b/library/std/src/sys/path/windows/tests.rs
index f2a60e3..9eb7920 100644
--- a/library/std/src/sys/path/windows/tests.rs
+++ b/library/std/src/sys/path/windows/tests.rs
@@ -135,3 +135,15 @@ fn broken_unc_path() {
assert_eq!(components.next(), Some(Component::Normal("foo".as_ref())));
assert_eq!(components.next(), Some(Component::Normal("bar".as_ref())));
}
+
+#[test]
+fn test_is_absolute_exact() {
+ use crate::sys::pal::api::wide_str;
+ // These paths can be made verbatim by only changing their prefix.
+ assert!(is_absolute_exact(wide_str!(r"C:\path\to\file")));
+ assert!(is_absolute_exact(wide_str!(r"\\server\share\path\to\file")));
+ // These paths change more substantially
+ assert!(!is_absolute_exact(wide_str!(r"C:\path\to\..\file")));
+ assert!(!is_absolute_exact(wide_str!(r"\\server\share\path\to\..\file")));
+ assert!(!is_absolute_exact(wide_str!(r"C:\path\to\NUL"))); // Converts to \\.\NUL
+}
diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs
index 06c15e0..4cfdf90 100644
--- a/library/std/src/sys/process/windows.rs
+++ b/library/std/src/sys/process/windows.rs
@@ -19,7 +19,7 @@
use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS};
use crate::sys::fs::{File, OpenOptions};
use crate::sys::handle::Handle;
-use crate::sys::pal::api::{self, WinError};
+use crate::sys::pal::api::{self, WinError, utf16};
use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf};
use crate::sys::pipe::{self, AnonPipe};
use crate::sys::{cvt, path, stdio};
@@ -880,9 +880,33 @@ fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut
fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
match d {
Some(dir) => {
- let mut dir_str: Vec<u16> = ensure_no_nuls(dir)?.encode_wide().collect();
- dir_str.push(0);
- Ok((dir_str.as_ptr(), dir_str))
+ let mut dir_str: Vec<u16> = ensure_no_nuls(dir)?.encode_wide().chain([0]).collect();
+ // Try to remove the `\\?\` prefix, if any.
+ // This is necessary because the current directory does not support verbatim paths.
+ // However. this can only be done if it doesn't change how the path will be resolved.
+ let ptr = if dir_str.starts_with(utf16!(r"\\?\UNC")) {
+ // Turn the `C` in `UNC` into a `\` so we can then use `\\rest\of\path`.
+ let start = r"\\?\UN".len();
+ dir_str[start] = b'\\' as u16;
+ if path::is_absolute_exact(&dir_str[start..]) {
+ dir_str[start..].as_ptr()
+ } else {
+ // Revert the above change.
+ dir_str[start] = b'C' as u16;
+ dir_str.as_ptr()
+ }
+ } else if dir_str.starts_with(utf16!(r"\\?\")) {
+ // Strip the leading `\\?\`
+ let start = r"\\?\".len();
+ if path::is_absolute_exact(&dir_str[start..]) {
+ dir_str[start..].as_ptr()
+ } else {
+ dir_str.as_ptr()
+ }
+ } else {
+ dir_str.as_ptr()
+ };
+ Ok((ptr, dir_str))
}
None => Ok((ptr::null(), Vec::new())),
}
diff --git a/rustfmt.toml b/rustfmt.toml
index c884a33..7c384b8 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -53,4 +53,8 @@
# Code automatically generated and included.
"compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",
"compiler/rustc_codegen_gcc/example",
+
+ # Rustfmt doesn't support use closures yet
+ "tests/mir-opt/ergonomic-clones/closure.rs",
+ "tests/codegen/ergonomic-clones/closure.rs",
]
diff --git a/src/bootstrap/defaults/bootstrap.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml
index f2cbe51..f0cb34e 100644
--- a/src/bootstrap/defaults/bootstrap.dist.toml
+++ b/src/bootstrap/defaults/bootstrap.dist.toml
@@ -17,7 +17,7 @@
[rust]
# We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`).
# Make sure they don't get set when installing from source.
-channel = "nightly"
+channel = "auto-detect"
# Never download a rustc, distributions must build a fresh compiler.
download-rustc = false
lld = true
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 8e42e84..e23c1ab 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -261,13 +261,7 @@ fn run(self, builder: &Builder<'_>) {
.args(builder.config.test_args())
.env("RUSTC", builder.rustc(compiler))
.env("RUSTDOC", builder.rustdoc(compiler));
- add_rustdoc_cargo_linker_args(
- &mut cmd,
- builder,
- compiler.host,
- LldThreads::No,
- compiler.stage,
- );
+ add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No);
cmd.delay_failure().run(builder);
}
}
@@ -845,7 +839,7 @@ fn run(self, builder: &Builder<'_>) {
.env("CFG_RELEASE_CHANNEL", &builder.config.channel)
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
.env("RUSTC_BOOTSTRAP", "1");
- cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage));
+ cmd.args(linker_args(builder, self.compiler.host, LldThreads::No));
cmd.delay_failure().run(builder);
}
@@ -1021,13 +1015,7 @@ fn run(self, builder: &Builder<'_>) {
cmd.env("RUSTDOC", builder.rustdoc(self.compiler))
.env("RUSTC", builder.rustc(self.compiler));
- add_rustdoc_cargo_linker_args(
- &mut cmd,
- builder,
- self.compiler.host,
- LldThreads::No,
- self.compiler.stage,
- );
+ add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No);
for path in &builder.paths {
if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) {
@@ -1796,7 +1784,7 @@ fn run(self, builder: &Builder<'_>) {
}
let mut hostflags = flags.clone();
- hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage));
+ hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No));
let mut targetflags = flags;
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index fc8d9d6..1c61f0a 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -819,7 +819,6 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
fields(build_compiler = ?self.build_compiler, target_compiler = ?self.target_compiler),
),
)]
-
fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
if builder.config.dry_run() {
return ToolBuildResult {
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index a96ccdd..e4503b2 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -260,7 +260,7 @@ fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
}
}
- for arg in linker_args(builder, compiler.host, LldThreads::Yes, 0) {
+ for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
self.hostflags.arg(&arg);
}
@@ -270,10 +270,10 @@ fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
}
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
// `linker_args` here.
- for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) {
+ for flag in linker_flags(builder, target, LldThreads::Yes) {
self.rustflags.arg(&flag);
}
- for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) {
+ for arg in linker_args(builder, target, LldThreads::Yes) {
self.rustdocflags.arg(&arg);
}
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index f002903..c32d9c2 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1276,7 +1276,6 @@ pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler {
),
),
)]
-
/// FIXME: This function is unnecessary (and dangerous, see <https://github.com/rust-lang/rust/issues/137469>).
/// We already have uplifting logic for the compiler, so remove this.
pub fn compiler_for(
@@ -1480,7 +1479,7 @@ pub fn rustdoc_cmd(&self, compiler: Compiler) -> BootstrapCommand {
cmd.arg("-Dwarnings");
}
cmd.arg("-Znormalize-docs");
- cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage));
+ cmd.args(linker_args(self, compiler.host, LldThreads::Yes));
cmd
}
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index e270c92..25ec64f 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1544,9 +1544,6 @@ pub(crate) fn parse_inner(
}
}
- let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
- let ci_channel = file_content.trim_end();
-
// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
// but not if `bootstrap.toml` hasn't been created.
let mut toml = if !using_default_path || toml_path.exists() {
@@ -1852,17 +1849,21 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
let mut lld_enabled = None;
let mut std_features = None;
- let is_user_configured_rust_channel =
- if let Some(channel) = toml.rust.as_ref().and_then(|r| r.channel.clone()) {
- if channel == "auto-detect" {
- config.channel = ci_channel.into();
- } else {
- config.channel = channel;
- }
+ let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
+ let ci_channel = file_content.trim_end();
+
+ let toml_channel = toml.rust.as_ref().and_then(|r| r.channel.clone());
+ let is_user_configured_rust_channel = match toml_channel {
+ Some(channel) if channel == "auto-detect" => {
+ config.channel = ci_channel.into();
true
- } else {
- false
- };
+ }
+ Some(channel) => {
+ config.channel = channel;
+ true
+ }
+ None => false,
+ };
let default = config.channel == "dev";
config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default);
@@ -1887,6 +1888,10 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
&& config.src.join(".cargo/config.toml").exists(),
);
+ if !is_user_configured_rust_channel && config.rust_info.is_from_tarball() {
+ config.channel = ci_channel.into();
+ }
+
if let Some(rust) = toml.rust {
let Rust {
optimize: optimize_toml,
@@ -2090,8 +2095,6 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
config.channel = channel;
}
- } else if config.rust_info.is_from_tarball() && !is_user_configured_rust_channel {
- ci_channel.clone_into(&mut config.channel);
}
if let Some(llvm) = toml.llvm {
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index dbfebd1..891340a 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -34,7 +34,6 @@ pub struct Finder {
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
- "wasm32-wali-linux-musl",
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 7c60e04..1a513a2 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -1557,7 +1557,7 @@ fn force_use_stage1(&self, stage: u32, target: TargetSelection) -> bool {
!self.config.full_bootstrap
&& !self.config.download_rustc()
&& stage >= 2
- && (self.hosts.iter().any(|h| *h == target) || target == self.build)
+ && (self.hosts.contains(&target) || target == self.build)
}
/// Checks whether the `compiler` compiling for `target` should be forced to
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 78dcdcb..1299fbb 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -432,9 +432,7 @@ pub fn dir_is_empty(dir: &Path) -> bool {
/// the "y" part from the string.
pub fn extract_beta_rev(version: &str) -> Option<String> {
let parts = version.splitn(2, "-beta.").collect::<Vec<_>>();
- let count = parts.get(1).and_then(|s| s.find(' ').map(|p| s[..p].to_string()));
-
- count
+ parts.get(1).and_then(|s| s.find(' ').map(|p| s[..p].to_string()))
}
pub enum LldThreads {
@@ -447,9 +445,8 @@ pub fn linker_args(
builder: &Builder<'_>,
target: TargetSelection,
lld_threads: LldThreads,
- stage: u32,
) -> Vec<String> {
- let mut args = linker_flags(builder, target, lld_threads, stage);
+ let mut args = linker_flags(builder, target, lld_threads);
if let Some(linker) = builder.linker(target) {
args.push(format!("-Clinker={}", linker.display()));
@@ -464,18 +461,12 @@ pub fn linker_flags(
builder: &Builder<'_>,
target: TargetSelection,
lld_threads: LldThreads,
- stage: u32,
) -> Vec<String> {
let mut args = vec![];
if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() {
match builder.config.lld_mode {
LldMode::External => {
- // cfg(bootstrap) - remove after updating bootstrap compiler (#137498)
- if stage == 0 && target.is_windows() {
- args.push("-Clink-arg=-fuse-ld=lld".to_string());
- } else {
- args.push("-Zlinker-features=+lld".to_string());
- }
+ args.push("-Zlinker-features=+lld".to_string());
// FIXME(kobzol): remove this flag once MCP510 gets stabilized
args.push("-Zunstable-options".to_string());
}
@@ -503,9 +494,8 @@ pub fn add_rustdoc_cargo_linker_args(
builder: &Builder<'_>,
target: TargetSelection,
lld_threads: LldThreads,
- stage: u32,
) {
- let args = linker_args(builder, target, lld_threads, stage);
+ let args = linker_args(builder, target, lld_threads);
let mut flags = cmd
.get_envs()
.find_map(|(k, v)| if k == OsStr::new("RUSTDOCFLAGS") { v } else { None })
diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs
index 7fbfad4..208a494 100644
--- a/src/ci/citool/src/analysis.rs
+++ b/src/ci/citool/src/analysis.rs
@@ -7,6 +7,7 @@
format_build_steps,
};
+use crate::github::JobInfoResolver;
use crate::metrics;
use crate::metrics::{JobMetrics, JobName, get_test_suites};
use crate::utils::{output_details, pluralize};
@@ -185,13 +186,19 @@ fn write_row(
}
/// Outputs a report of test differences between the `parent` and `current` commits.
-pub fn output_test_diffs(job_metrics: &HashMap<JobName, JobMetrics>) {
+pub fn output_test_diffs(
+ job_metrics: &HashMap<JobName, JobMetrics>,
+ job_info_resolver: &mut JobInfoResolver,
+) {
let aggregated_test_diffs = aggregate_test_diffs(&job_metrics);
- report_test_diffs(aggregated_test_diffs);
+ report_test_diffs(aggregated_test_diffs, job_metrics, job_info_resolver);
}
/// Prints the ten largest differences in bootstrap durations.
-pub fn output_largest_duration_changes(job_metrics: &HashMap<JobName, JobMetrics>) {
+pub fn output_largest_duration_changes(
+ job_metrics: &HashMap<JobName, JobMetrics>,
+ job_info_resolver: &mut JobInfoResolver,
+) {
struct Entry<'a> {
job: &'a JobName,
before: Duration,
@@ -225,14 +232,14 @@ struct Entry<'a> {
});
}
}
- changes.sort_by(|e1, e2| e1.change.partial_cmp(&e2.change).unwrap().reverse());
+ changes.sort_by(|e1, e2| e1.change.abs().partial_cmp(&e2.change.abs()).unwrap().reverse());
println!("# Job duration changes");
for (index, entry) in changes.into_iter().take(10).enumerate() {
println!(
- "{}. `{}`: {:.1}s -> {:.1}s ({:.1}%)",
+ "{}. {}: {:.1}s -> {:.1}s ({:.1}%)",
index + 1,
- entry.job,
+ format_job_link(job_info_resolver, job_metrics, entry.job),
entry.before.as_secs_f64(),
entry.after.as_secs_f64(),
entry.change
@@ -400,7 +407,11 @@ fn generate_test_name(name: &str) -> String {
}
/// Prints test changes in Markdown format to stdout.
-fn report_test_diffs(diff: AggregatedTestDiffs) {
+fn report_test_diffs(
+ diff: AggregatedTestDiffs,
+ job_metrics: &HashMap<JobName, JobMetrics>,
+ job_info_resolver: &mut JobInfoResolver,
+) {
println!("# Test differences");
if diff.diffs.is_empty() {
println!("No test diffs found");
@@ -521,9 +532,26 @@ fn format_job_group(group: u64) -> String {
println!(
"- {}: {}",
format_job_group(group as u64),
- jobs.iter().map(|j| format!("`{j}`")).collect::<Vec<_>>().join(", ")
+ jobs.iter()
+ .map(|j| format_job_link(job_info_resolver, job_metrics, j))
+ .collect::<Vec<_>>()
+ .join(", ")
);
}
},
);
}
+
+/// Tries to get a GitHub Actions job summary URL from the resolver.
+/// If it is not available, just wraps the job name in backticks.
+fn format_job_link(
+ job_info_resolver: &mut JobInfoResolver,
+ job_metrics: &HashMap<JobName, JobMetrics>,
+ job_name: &str,
+) -> String {
+ job_metrics
+ .get(job_name)
+ .and_then(|metrics| job_info_resolver.get_job_summary_link(job_name, &metrics.current))
+ .map(|summary_url| format!("[{job_name}]({summary_url})"))
+ .unwrap_or_else(|| format!("`{job_name}`"))
+}
diff --git a/src/ci/citool/src/github.rs b/src/ci/citool/src/github.rs
new file mode 100644
index 0000000..35e4c3f
--- /dev/null
+++ b/src/ci/citool/src/github.rs
@@ -0,0 +1,109 @@
+use std::collections::HashMap;
+
+use anyhow::Context;
+use build_helper::metrics::{CiMetadata, JsonRoot};
+
+pub struct GitHubClient;
+
+impl GitHubClient {
+ fn get_workflow_run_jobs(
+ &self,
+ repo: &str,
+ workflow_run_id: u64,
+ ) -> anyhow::Result<Vec<GitHubJob>> {
+ let req = ureq::get(format!(
+ "https://api.github.com/repos/{repo}/actions/runs/{workflow_run_id}/jobs?per_page=100"
+ ))
+ .header("User-Agent", "rust-lang/rust/citool")
+ .header("Accept", "application/vnd.github+json")
+ .header("X-GitHub-Api-Version", "2022-11-28")
+ .call()
+ .context("cannot get workflow job list")?;
+
+ let status = req.status();
+ let mut body = req.into_body();
+ if status.is_success() {
+ // This API response is actually paged, but we assume for now that there are at
+ // most 100 jobs per workflow.
+ let response = body
+ .read_json::<WorkflowRunJobsResponse>()
+ .context("cannot deserialize workflow run jobs response")?;
+ // The CI job names have a prefix, e.g. `auto - foo`. We remove the prefix here to
+ // normalize the job name.
+ Ok(response
+ .jobs
+ .into_iter()
+ .map(|mut job| {
+ job.name = job
+ .name
+ .split_once(" - ")
+ .map(|res| res.1.to_string())
+ .unwrap_or_else(|| job.name);
+ job
+ })
+ .collect())
+ } else {
+ Err(anyhow::anyhow!(
+ "Cannot get jobs of workflow run {workflow_run_id}: {status}\n{}",
+ body.read_to_string()?
+ ))
+ }
+ }
+}
+
+#[derive(serde::Deserialize)]
+struct WorkflowRunJobsResponse {
+ jobs: Vec<GitHubJob>,
+}
+
+#[derive(serde::Deserialize)]
+struct GitHubJob {
+ name: String,
+ id: u64,
+}
+
+/// Can be used to resolve information about GitHub Actions jobs.
+/// Caches results internally to avoid too unnecessary GitHub API calls.
+pub struct JobInfoResolver {
+ client: GitHubClient,
+ // Workflow run ID -> jobs
+ workflow_job_cache: HashMap<u64, Vec<GitHubJob>>,
+}
+
+impl JobInfoResolver {
+ pub fn new() -> Self {
+ Self { client: GitHubClient, workflow_job_cache: Default::default() }
+ }
+
+ /// Get a link to a job summary for the given job name and bootstrap execution.
+ pub fn get_job_summary_link(&mut self, job_name: &str, metrics: &JsonRoot) -> Option<String> {
+ metrics.ci_metadata.as_ref().and_then(|metadata| {
+ self.get_job_id(metadata, job_name).map(|job_id| {
+ format!(
+ "https://github.com/{}/actions/runs/{}#summary-{job_id}",
+ metadata.repository, metadata.workflow_run_id
+ )
+ })
+ })
+ }
+
+ fn get_job_id(&mut self, ci_metadata: &CiMetadata, job_name: &str) -> Option<u64> {
+ if let Some(job) = self
+ .workflow_job_cache
+ .get(&ci_metadata.workflow_run_id)
+ .and_then(|jobs| jobs.iter().find(|j| j.name == job_name))
+ {
+ return Some(job.id);
+ }
+
+ let jobs = self
+ .client
+ .get_workflow_run_jobs(&ci_metadata.repository, ci_metadata.workflow_run_id)
+ .inspect_err(|e| eprintln!("Cannot download workflow jobs: {e:?}"))
+ .ok()?;
+ let job_id = jobs.iter().find(|j| j.name == job_name).map(|j| j.id);
+ // Save the cache even if the job name was not found, it could be useful for further lookups
+ self.workflow_job_cache.insert(ci_metadata.workflow_run_id, jobs);
+ job_id
+ }
+}
diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs
index 6db5eab..a1956da 100644
--- a/src/ci/citool/src/main.rs
+++ b/src/ci/citool/src/main.rs
@@ -1,6 +1,7 @@
mod analysis;
mod cpu_usage;
mod datadog;
+mod github;
mod jobs;
mod metrics;
mod utils;
@@ -18,6 +19,7 @@
use crate::analysis::{output_largest_duration_changes, output_test_diffs};
use crate::cpu_usage::load_cpu_usage;
use crate::datadog::upload_datadog_metric;
+use crate::github::JobInfoResolver;
use crate::jobs::RunType;
use crate::metrics::{JobMetrics, download_auto_job_metrics, download_job_metrics, load_metrics};
use crate::utils::load_env_var;
@@ -145,6 +147,7 @@ fn postprocess_metrics(
) -> anyhow::Result<()> {
let metrics = load_metrics(&metrics_path)?;
+ let mut job_info_resolver = JobInfoResolver::new();
if let (Some(parent), Some(job_name)) = (parent, job_name) {
// This command is executed also on PR builds, which might not have parent metrics
// available, because some PR jobs don't run on auto builds, and PR jobs do not upload metrics
@@ -160,7 +163,7 @@ fn postprocess_metrics(
job_name,
JobMetrics { parent: Some(parent_metrics), current: metrics },
)]);
- output_test_diffs(&job_metrics);
+ output_test_diffs(&job_metrics, &mut job_info_resolver);
return Ok(());
}
Err(error) => {
@@ -180,8 +183,10 @@ fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow
let metrics = download_auto_job_metrics(&db, &parent, ¤t)?;
println!("\nComparing {parent} (parent) -> {current} (this PR)\n");
- output_test_diffs(&metrics);
- output_largest_duration_changes(&metrics);
+
+ let mut job_info_resolver = JobInfoResolver::new();
+ output_test_diffs(&metrics, &mut job_info_resolver);
+ output_largest_duration_changes(&metrics, &mut job_info_resolver);
Ok(())
}
diff --git a/src/doc/rustc-dev-guide/src/solve/opaque-types.md b/src/doc/rustc-dev-guide/src/solve/opaque-types.md
index 672aab7..509c34a 100644
--- a/src/doc/rustc-dev-guide/src/solve/opaque-types.md
+++ b/src/doc/rustc-dev-guide/src/solve/opaque-types.md
@@ -33,7 +33,7 @@
always done in two steps. Outside of the defining scope `normalizes-to` for opaques always
returns `Err(NoSolution)`.
-We start by trying to to assign the expected type as a hidden type.
+We start by trying to assign the expected type as a hidden type.
In the implicit-negative coherence mode, this currently always results in ambiguity without
interacting with the opaque types storage. We could instead add allow 'defining' all opaque types,
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 8e4a710..4ec2909 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -191,8 +191,13 @@
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
16, ptr` will only run if it supports the comma-separated list of atomic
widths.
-- `needs-dynamic-linking` - ignores if target does not support dynamic linking
+- `needs-dynamic-linking` — ignores if target does not support dynamic linking
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
+- `needs-crate-type` — ignores if target platform does not support one or more
+ of the comma-delimited list of specified crate types. For example,
+ `//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
+ on `wasm32-unknown-unknown` target because the target does not support the
+ `proc-macro` crate type.
The following directives will check LLVM support:
@@ -229,14 +234,14 @@
### Affecting how tests are built
-| Directive | Explanation | Supported test suites | Possible values |
-|---------------------|----------------------------------------------------------------------------------------------|---------------------------|------------------------------------------------------------------------------|
-| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental`. |
-| `edition` | Alias for `compile-flags: --edition=xxx` | All except for `run-make` | Any valid `--edition` value |
-| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `<KEY>=<VALUE>` |
-| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name |
-| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
-| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
+| Directive | Explanation | Supported test suites | Possible values |
+|---------------------|----------------------------------------------------------------------------------------------|---------------------------|--------------------------------------------------------------------------------------------|
+| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
+| `edition` | The edition used to build the test | All except for `run-make` | Any valid `--edition` value |
+| `rustc-env` | Env var to set when running `rustc` | All except for `run-make` | `<KEY>=<VALUE>` |
+| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make` | Any env var name |
+| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
+| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
<div class="warning">
Tests (outside of `run-make`) that want to use incremental tests not in the
diff --git a/src/doc/unstable-book/src/language-features/offset-of-enum.md b/src/doc/unstable-book/src/language-features/offset-of-enum.md
index 1960d62..78c0d87 100644
--- a/src/doc/unstable-book/src/language-features/offset-of-enum.md
+++ b/src/doc/unstable-book/src/language-features/offset-of-enum.md
@@ -1,4 +1,4 @@
-# `offset_of_slice`
+# `offset_of_enum`
The tracking issue for this feature is: [#120141]
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e0e09b5..3a2b697 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -497,7 +497,7 @@ pub(crate) fn build_impl(
};
let trait_item = tcx
.associated_items(associated_trait.def_id)
- .find_by_name_and_kind(
+ .find_by_ident_and_kind(
tcx,
item.ident,
assoc_kind,
@@ -524,7 +524,7 @@ pub(crate) fn build_impl(
if let Some(associated_trait) = associated_trait {
let trait_item = tcx
.associated_items(associated_trait.def_id)
- .find_by_name_and_kind(
+ .find_by_ident_and_kind(
tcx,
item.ident(tcx),
item.kind,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ee6008b..45a9157 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1088,7 +1088,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
enum FunctionArgs<'tcx> {
Body(hir::BodyId),
- Names(&'tcx [Option<Ident>]),
+ Idents(&'tcx [Option<Ident>]),
}
fn clean_function<'tcx>(
@@ -1104,8 +1104,8 @@ fn clean_function<'tcx>(
FunctionArgs::Body(body_id) => {
clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id)
}
- FunctionArgs::Names(names) => {
- clean_args_from_types_and_names(cx, sig.decl.inputs, names)
+ FunctionArgs::Idents(idents) => {
+ clean_args_from_types_and_names(cx, sig.decl.inputs, idents)
}
};
let decl = clean_fn_decl_with_args(cx, sig.decl, Some(&sig.header), args);
@@ -1117,7 +1117,7 @@ fn clean_function<'tcx>(
fn clean_args_from_types_and_names<'tcx>(
cx: &mut DocContext<'tcx>,
types: &[hir::Ty<'tcx>],
- names: &[Option<Ident>],
+ idents: &[Option<Ident>],
) -> Arguments {
fn nonempty_name(ident: &Option<Ident>) -> Option<Symbol> {
if let Some(ident) = ident
@@ -1131,7 +1131,7 @@ fn nonempty_name(ident: &Option<Ident>) -> Option<Symbol> {
// If at least one argument has a name, use `_` as the name of unnamed
// arguments. Otherwise omit argument names.
- let default_name = if names.iter().any(|ident| nonempty_name(ident).is_some()) {
+ let default_name = if idents.iter().any(|ident| nonempty_name(ident).is_some()) {
kw::Underscore
} else {
kw::Empty
@@ -1143,7 +1143,7 @@ fn nonempty_name(ident: &Option<Ident>) -> Option<Symbol> {
.enumerate()
.map(|(i, ty)| Argument {
type_: clean_ty(ty, cx),
- name: names.get(i).and_then(nonempty_name).unwrap_or(default_name),
+ name: idents.get(i).and_then(nonempty_name).unwrap_or(default_name),
is_const: false,
})
.collect(),
@@ -1193,7 +1193,7 @@ fn clean_poly_fn_sig<'tcx>(
did: Option<DefId>,
sig: ty::PolyFnSig<'tcx>,
) -> FnDecl {
- let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_names(did)).iter();
+ let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_idents(did)).iter();
// We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
// but shouldn't change any code meaning.
@@ -1270,8 +1270,8 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body));
MethodItem(m, None)
}
- hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
- let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names));
+ hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(idents)) => {
+ let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Idents(idents));
RequiredMethodItem(m)
}
hir::TraitItemKind::Type(bounds, Some(default)) => {
@@ -2612,7 +2612,7 @@ fn clean_bare_fn_ty<'tcx>(
.filter(|p| !is_elided_lifetime(p))
.map(|x| clean_generic_param(cx, None, x))
.collect();
- let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
+ let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_idents);
let decl = clean_fn_decl_with_args(cx, bare_fn.decl, None, args);
(generic_params, decl)
});
@@ -3148,8 +3148,8 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
let def_id = item.owner_id.to_def_id();
cx.with_param_env(def_id, |cx| {
let kind = match item.kind {
- hir::ForeignItemKind::Fn(sig, names, generics) => ForeignFunctionItem(
- clean_function(cx, &sig, generics, FunctionArgs::Names(names)),
+ hir::ForeignItemKind::Fn(sig, idents, generics) => ForeignFunctionItem(
+ clean_function(cx, &sig, generics, FunctionArgs::Idents(idents)),
sig.header.safety(),
),
hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index c47e426..c4dea79 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -321,6 +321,7 @@ pub(crate) fn create_config(
(rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
};
}),
+ extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index a2808bd..88eaa52 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -191,6 +191,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
hash_untracked_state: None,
register_lints: Some(Box::new(crate::lint::register_lints)),
override_queries: None,
+ extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 334a7a8..44134bd 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -721,7 +721,7 @@ pub(crate) fn find_codes<T: doctest::DocTestVisitor>(
extra_info: Option<&ExtraInfo<'_>>,
include_non_rust: bool,
) {
- let mut parser = Parser::new(doc).into_offset_iter();
+ let mut parser = Parser::new_ext(doc, main_body_opts()).into_offset_iter();
let mut prev_offset = 0;
let mut nb_lines = 0;
let mut register_header = None;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 3512dff..21c823f 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -13,6 +13,9 @@
//! is cloned per-thread and contains information about what is currently being
//! rendered.
//!
+//! The main entry point to the rendering system is the implementation of
+//! `FormatRenderer` on `Context`.
+//!
//! In order to speed up rendering (mostly because of markdown rendering), the
//! rendering process has been parallelized. This parallelization is only
//! exposed through the `crate` method on the context, and then also from the
@@ -90,7 +93,7 @@ pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
/// impl.
#[derive(Copy, Clone, Debug)]
-pub(crate) enum AssocItemRender<'a> {
+enum AssocItemRender<'a> {
All,
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
}
@@ -98,7 +101,7 @@ pub(crate) enum AssocItemRender<'a> {
/// For different handling of associated items from the Deref target of a type rather than the type
/// itself.
#[derive(Copy, Clone, PartialEq)]
-pub(crate) enum RenderMode {
+enum RenderMode {
Normal,
ForDeref { mut_: bool },
}
@@ -126,7 +129,7 @@ pub(crate) struct IndexItem {
/// A type used for the search index.
#[derive(Debug, Eq, PartialEq)]
-pub(crate) struct RenderType {
+struct RenderType {
id: Option<RenderTypeId>,
generics: Option<Vec<RenderType>>,
bindings: Option<Vec<(RenderTypeId, Vec<RenderType>)>>,
@@ -137,7 +140,7 @@ impl RenderType {
// The contents of the lists are always integers in self-terminating hex
// form, handled by `RenderTypeId::write_to_string`, so no commas are
// needed to separate the items.
- pub fn write_to_string(&self, string: &mut String) {
+ fn write_to_string(&self, string: &mut String) {
fn write_optional_id(id: Option<RenderTypeId>, string: &mut String) {
// 0 is a sentinel, everything else is one-indexed
match id {
@@ -177,7 +180,7 @@ fn write_optional_id(id: Option<RenderTypeId>, string: &mut String) {
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub(crate) enum RenderTypeId {
+enum RenderTypeId {
DefId(DefId),
Primitive(clean::PrimitiveType),
AssociatedType(Symbol),
@@ -186,7 +189,7 @@ pub(crate) enum RenderTypeId {
}
impl RenderTypeId {
- pub fn write_to_string(&self, string: &mut String) {
+ fn write_to_string(&self, string: &mut String) {
let id: i32 = match &self {
// 0 is a sentinel, everything else is one-indexed
// concrete type
@@ -209,7 +212,7 @@ pub(crate) struct IndexItemFunctionType {
}
impl IndexItemFunctionType {
- pub fn write_to_string<'a>(
+ fn write_to_string<'a>(
&'a self,
string: &mut String,
backref_queue: &mut VecDeque<&'a IndexItemFunctionType>,
@@ -309,7 +312,7 @@ fn new(mut url: String, name: String) -> ItemEntry {
}
impl ItemEntry {
- pub(crate) fn print(&self) -> impl fmt::Display {
+ fn print(&self) -> impl fmt::Display {
fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
}
}
@@ -760,7 +763,7 @@ fn short_item_info(
// Render the list of items inside one of the sections "Trait Implementations",
// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
-pub(crate) fn render_impls(
+fn render_impls(
cx: &Context<'_>,
mut w: impl Write,
impls: &[&Impl],
@@ -1201,7 +1204,7 @@ fn anchor(&self, id: &'a str) -> Self {
}
}
-pub fn write_section_heading(
+fn write_section_heading(
title: &str,
id: &str,
extra_class: Option<&str>,
@@ -1226,7 +1229,7 @@ fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
write_section_heading(title, id, None, "")
}
-pub(crate) fn render_all_impls(
+fn render_all_impls(
mut w: impl Write,
cx: &Context<'_>,
containing_item: &clean::Item,
@@ -1473,10 +1476,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
}
}
-pub(crate) fn notable_traits_button(
- ty: &clean::Type,
- cx: &Context<'_>,
-) -> Option<impl fmt::Display> {
+fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt::Display> {
if ty.is_unit() {
// Very common fast path.
return None;
@@ -1588,10 +1588,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
(format!("{:#}", ty.print(cx)), out)
}
-pub(crate) fn notable_traits_json<'a>(
- tys: impl Iterator<Item = &'a clean::Type>,
- cx: &Context<'_>,
-) -> String {
+fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
struct NotableTraitsMap(Vec<(String, String)>);
@@ -2171,7 +2168,7 @@ fn render_rightside(
})
}
-pub(crate) fn render_impl_summary(
+fn render_impl_summary(
cx: &Context<'_>,
i: &Impl,
parent: &clean::Item,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index aa8df35..74d23b3 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1447,7 +1447,7 @@
cursor: pointer;
}
.setting-check input {
- flex-shrink: 0,
+ flex-shrink: 0;
}
.setting-radio input:checked {
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index bcdca86..692ce21 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -91,19 +91,21 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
if let clean::ImportItem(clean::Import { source, .. }) = &i.kind
&& let Some(source_did) = source.did
- && let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local())
{
- let reexports = reexport_chain(self.tcx, import_def_id, source_did);
-
- // Check if any reexport in the chain has a hidden source
- let has_hidden_source = reexports
- .iter()
- .filter_map(|reexport| reexport.id())
- .any(|reexport_did| self.tcx.is_doc_hidden(reexport_did))
- || self.tcx.is_doc_hidden(source_did);
-
- if has_hidden_source {
+ if self.tcx.is_doc_hidden(source_did) {
return None;
+ } else if let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local()) {
+ let reexports = reexport_chain(self.tcx, import_def_id, source_did);
+
+ // Check if any reexport in the chain has a hidden source
+ let has_hidden_source = reexports
+ .iter()
+ .filter_map(|reexport| reexport.id())
+ .any(|reexport_did| self.tcx.is_doc_hidden(reexport_did));
+
+ if has_hidden_source {
+ return None;
+ }
}
}
diff --git a/src/stage0 b/src/stage0
index 9d6a08d..b3841d2 100644
--- a/src/stage0
+++ b/src/stage0
@@ -14,468 +14,466 @@
# All changes below this comment will be overridden the next time the
# tool is executed.
-compiler_date=2025-02-18
+compiler_date=2025-04-02
compiler_version=beta
-rustfmt_date=2025-02-18
+rustfmt_date=2025-04-02
rustfmt_version=nightly
-dist/2025-02-18/rustc-beta-aarch64-apple-darwin.tar.gz=1b51ca064350d8b15c7ab6c8ec996a497e912dc237cafc2c205066fc6416e0ff
-dist/2025-02-18/rustc-beta-aarch64-apple-darwin.tar.xz=e4b71f6456d9e62ada6909254606da7f6681f3da0f5bc7d2c3d5c387fea35743
-dist/2025-02-18/rustc-beta-aarch64-pc-windows-msvc.tar.gz=1ff70a5bd238d959d806c3b471a5b03c6cde784944a96a585e0ae0837d2a9c92
-dist/2025-02-18/rustc-beta-aarch64-pc-windows-msvc.tar.xz=5017b351bb90a08041757eae61386b224ec0161c5734293184a87d8903f30098
-dist/2025-02-18/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=8a58b6cc4577615efc76bb9472229098d6f938c1f051ea540409e9dc812dbd8f
-dist/2025-02-18/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=330e217dbd1c507c8706aef5fbd0baf9584495445743f38668cdc962adfb125e
-dist/2025-02-18/rustc-beta-aarch64-unknown-linux-musl.tar.gz=4060ec54281975880a9819b815120d6a450e4c31ddf1136ecce348e28875d50d
-dist/2025-02-18/rustc-beta-aarch64-unknown-linux-musl.tar.xz=0f92b9267a55ac0c764cde63b8cbc8a0a317f7e0817185d380fc2aa35a933687
-dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=4e989e00725e7cfb08ea834c74ec6dd352eda74c13218f7da423ed598af9f9df
-dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=b06181daf8842c2e544e5d54169f9bbfc70ee76115495de033ac4e341617a588
-dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=93fe2efcde1032ad636ef509a73168f0ab7fadbca699a27e2882b3832539e8fa
-dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=b49d0256381c928785035578e5b7624c37ba732ea7aefca37dbb66b5162c8090
-dist/2025-02-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=56fd36c20d78085f39f0df40f15f7694e8744714104539865b9c3d7b06d47e2f
-dist/2025-02-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=86587bea60c2b8a114ab33fe65a7152fcf8e1dcca14550712dca72af9fd65674
-dist/2025-02-18/rustc-beta-i686-pc-windows-gnu.tar.gz=32c95c78b223efea2ee8e02fbe3a58ac753ce9284e792bc87feaa051fcff5687
-dist/2025-02-18/rustc-beta-i686-pc-windows-gnu.tar.xz=d2e623f11aee7e81eceb6947e3f7150bfd727eb2f527e4abc6b10d3322959802
-dist/2025-02-18/rustc-beta-i686-pc-windows-msvc.tar.gz=f7ffd07eb2b5e83df513c6a313e28003e3ce923778583e78da9efbb5e62405dc
-dist/2025-02-18/rustc-beta-i686-pc-windows-msvc.tar.xz=cd2e61b548a6849b17183fcacb2ac8f94955d893be439793580c39080feb28be
-dist/2025-02-18/rustc-beta-i686-unknown-linux-gnu.tar.gz=fedeca202c1651fe4b15cfc411365ecf016376b3cc7c772d2e0d739e0ec02dc6
-dist/2025-02-18/rustc-beta-i686-unknown-linux-gnu.tar.xz=6389f10e2328bdfa81ef1f34406bb4ec8bcb6dcf64d39c95946d32c9fee7f0b7
-dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=21b565bbaacc2be5d066c5d0c49b7c0f5b0bd24690ca35e9c88e6ec91846f744
-dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=4a728e3ec41834775f0b288cdca5ae152314edcaf20d7ea46ea62fab1b9ef327
-dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=0a72f650aa70708f9a72886ea33b7a2e3ffe2a6e2cbcb1d2248f3d9eca74a9d4
-dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=877c3c447f4c25068f70bd7d6dd5078d75b0c194777b2f8a9311a66fc6eda701
-dist/2025-02-18/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=67af5e05ab0a367d3f76c0656823b530a23fb26d9c86db2b433684b9191b8881
-dist/2025-02-18/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=2da086d39eaa000ba629ee15bec740db57039ca3e5c7c55feb9cb9ca6d39c785
-dist/2025-02-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=b079df9a3e5be95a755d22f5ecf3ddeb43f94d96eaa3985770ae98ad0e7e15bb
-dist/2025-02-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=916fe3b67094bb351320371de9587f01bb65f9b9aed2c7aff7930e499822b660
-dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=356e3173c960aadfb91dcb607a26647895fb1ae11a7cb596b019c71c6dd808e7
-dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=9115c4c85d8c4b5254df41a5d3f55733648ba282711e18a692ee100ed13fb550
-dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=b8a267f9ca2d23385c529924782f633b6b9f66b50cda5986eff91c223d715307
-dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=84e65fc1d4282d737b6d0b1aaa1c2abd395af215983eb5b3700e925ca6ba3bc3
-dist/2025-02-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=19b1d8618edb5d3a6cf620c814f6b76a462bc965f4aac2cde7aca5849b92cac9
-dist/2025-02-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=9914408b5590fe7c43b2aa10c261bb5162b024e396c625b06546564a5eaddb89
-dist/2025-02-18/rustc-beta-s390x-unknown-linux-gnu.tar.gz=37ac73ea85f43a4859d8c4526cb9480e69bcaa778e842128852c8b21c6db6b45
-dist/2025-02-18/rustc-beta-s390x-unknown-linux-gnu.tar.xz=af1cab661b26cab1ade53f12ec08d13d60a74c2f370d9d3617154e0f01cb3719
-dist/2025-02-18/rustc-beta-x86_64-apple-darwin.tar.gz=aa9999ad56f8968e3e0f5417661ff42fbd1bd482a649d1a8c01d6ba5a6e78a72
-dist/2025-02-18/rustc-beta-x86_64-apple-darwin.tar.xz=bfd09bf8db9bbd7557df3f206207631cc4b10d59d0cf6b072e610646b5c7fa4a
-dist/2025-02-18/rustc-beta-x86_64-pc-windows-gnu.tar.gz=dabab346a003a5b13265da6bab96fc703c34f728c852092bec4cf08d13daeadc
-dist/2025-02-18/rustc-beta-x86_64-pc-windows-gnu.tar.xz=c2252dea69c8dcf6ba0213da8b05b8d9173676fb7448cde684da7b56d2c52577
-dist/2025-02-18/rustc-beta-x86_64-pc-windows-msvc.tar.gz=9ae9c3cb963872b2ef02650bcec15906e0b5e89cc6d3bee0aadfffcec7a1e6df
-dist/2025-02-18/rustc-beta-x86_64-pc-windows-msvc.tar.xz=bcbf75c92e9afe6b25bbde275bd38c3cdeda6324baf5b8c99173ca5738760a7f
-dist/2025-02-18/rustc-beta-x86_64-unknown-freebsd.tar.gz=5313d0780f6a9587e809da0f1ffc973721afad88a0ef8fb83005c383d79229d8
-dist/2025-02-18/rustc-beta-x86_64-unknown-freebsd.tar.xz=52ab3212d64b56a8da207fe976cbc8d266e962a61c742e6069137b10ff25c3c1
-dist/2025-02-18/rustc-beta-x86_64-unknown-illumos.tar.gz=527f839ddedc7bdff48527a276d3d7f64d475dd815b81c6664f1ce25668e0ce4
-dist/2025-02-18/rustc-beta-x86_64-unknown-illumos.tar.xz=3861d9928983a415cd44e5dc50a99af948fac392adfb6c2147b14fb98dd08890
-dist/2025-02-18/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=0054d14cf00b25cfbcb2a1560887c825f703223312ca9cdd0ad51076bf54a3cc
-dist/2025-02-18/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=75a9d69d13e50bb22ec721f9c64d08282d76f285482b285bb61bacabeecd710c
-dist/2025-02-18/rustc-beta-x86_64-unknown-linux-musl.tar.gz=305765ca6a413ea86360b970bd062a19f6bc52756551af43d74920fc2a021d95
-dist/2025-02-18/rustc-beta-x86_64-unknown-linux-musl.tar.xz=c7230b578a97fb234ac106c7333615074b9a7a8abc1422f149ad613c2af28134
-dist/2025-02-18/rustc-beta-x86_64-unknown-netbsd.tar.gz=881bd9b260b2c7838ea1b4de2cd6baf2ff4d317e0c159faba1a683c4c32ba267
-dist/2025-02-18/rustc-beta-x86_64-unknown-netbsd.tar.xz=0c4f2cc0bafbf8b41b257e851870b64d3b5fc112f02227f561c645dc439c96db
-dist/2025-02-18/rust-std-beta-aarch64-apple-darwin.tar.gz=958434edfc07bf6d10da3d41f01d1511b28d1178423a78bff2f60cd10046dbca
-dist/2025-02-18/rust-std-beta-aarch64-apple-darwin.tar.xz=80043af05fb96c497bce55063f2733e37f243f85084f9aa60ab504d7c15c5cce
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios.tar.gz=509aa8803b29ccbb97a1a8c12e2ca6b27310d5af313650c7afff45ab1843106a
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios.tar.xz=f0f05dafc9a3277b075023bb449675946706307f769590c065cb53ae615708d9
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=c37c0aee56c5858f91fb5aa60df28cc92649d4884d5edde57eb6690f494ba5f5
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=e5120697e4a118824fdebf6d2a644f8f338bb83e209303fc684095b8f6b4ab1c
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios-sim.tar.gz=d5b851917a3f57703378596828e92068c28e00fe0b02331891737c2fc697b5ff
-dist/2025-02-18/rust-std-beta-aarch64-apple-ios-sim.tar.xz=ef33164320931007db65f4915b533e5078a7279a7a134fc80045751a5198834a
-dist/2025-02-18/rust-std-beta-aarch64-linux-android.tar.gz=4b94607d7c09b4f0f85236fb2237f1859150e12745ee2020cb134db904c1e05b
-dist/2025-02-18/rust-std-beta-aarch64-linux-android.tar.xz=3aa7807ef9da83e1a4deebe4a7085e4df1b60edd4e9f237870f827073100d09c
-dist/2025-02-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=2d4c8a5a400c35443228087f8203f320253299a5018c1b92526f99023581c3e9
-dist/2025-02-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=df8741055b3d4f7eeedec9e0101a1c184a37ffb75b2d4474bfbca577300355f2
-dist/2025-02-18/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=8db9c07d4b68018cd3c67be1e7bc496078dfa8a6852a35c449db5ba19f6bf0df
-dist/2025-02-18/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=f112e3d51013ceff37e8c05d80c3605b76ddec8e55474d55815b4860f96febc8
-dist/2025-02-18/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=2bb6d934225823c2dcdb86dca91dd8e488f69b238b283607f75abe9b5de46486
-dist/2025-02-18/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=99036fde94fe0cb3ab2d2f48cd9f9bbb4d2fa784f1bd21afaa71b032cd95b069
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=c49fee34a02f5d3fe4e03ed7da90e045f7967c3e2e8f7a30804f4da5d535225c
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=88170a13f9448b9671d252f0315aed94b6324716230db7307061d4890cfda70a
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=a5e7442d722f6742fd0436d3c7d75738bc6cbd936f3399190086a88ef311e34e
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=5d07a95e3203ebe98eed1b271a2e6ae44bead53e7bda019a8d256c8553c21bd1
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=0af6b8fc7f46641d4de61ada9bc9ff01af7775d727121267177fa4c43cc9ed7b
-dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=fd68b34e7aba25d8a834c018febbde6c3de7d967e014a738681642f41ec61603
-dist/2025-02-18/rust-std-beta-aarch64-unknown-none.tar.gz=46025b0892498de8e311be7bd6df261065f80a70720cb9285062161a30af5d76
-dist/2025-02-18/rust-std-beta-aarch64-unknown-none.tar.xz=b4cbf42364270c158d801ac7d4b6cfd7bf1f5f9e74a3044e6d959f1971f5bc34
-dist/2025-02-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=ae2a5c63cce6ce237c81ae78cabc6e1e0634c956789c2e2f39e3a6c0d864636f
-dist/2025-02-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=6bba5069c89d9a0d9a2013715814fb55ebcd77b342ed0dfc72115a18367c5e8c
-dist/2025-02-18/rust-std-beta-aarch64-unknown-uefi.tar.gz=0bef07ceece7523d6f41f1d640569c52ebe8a6b97b35da84240d873fd68250da
-dist/2025-02-18/rust-std-beta-aarch64-unknown-uefi.tar.xz=cff8b58e158786cee1a719552fb97cb2cd3a12b541641437809428a65eed42fa
-dist/2025-02-18/rust-std-beta-arm-linux-androideabi.tar.gz=a34fbf0d01cea60876a6d0aa4ee96587a5e31b6d4f84aa7c1ba5b7fed261b639
-dist/2025-02-18/rust-std-beta-arm-linux-androideabi.tar.xz=7d72d638f5984726fb4a61e81671d9557d0a9a876bf5bbf39b2df3c9983d2962
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=9ef3aa1bcbe1a18658bd16359cbf3e94ae1b07f65bd5c69ffbfa964ad845baf5
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=93020195c2ce07204179e2d2f900953707e341a71d9371551c4a727afc58378e
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=5b0a4c4831534de85a5ba5b0149bbd824ca83648bf66babe5dbf13291b06e03d
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=60f1ff95cc88330b6c9741520c02ec845e7b14943f2927091a9110b7fb1c4305
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=0f254a943b6e56873d2ab84e8a93fa7a3ab723df5a7926faeadae4696ed06121
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0c682e7cbba8463682a0a20785ff7fd331d2bc7a32c0cf86b8159897fc5c5ee7
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=6c5be45f79035f57ac41fd209f6e7d4439cab5acaa766f7bf001b24196411b1e
-dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=bf25eb6650ad27377414d53af6857133a539530c841cf96e3cae4406bf4ad485
-dist/2025-02-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=39ec7fd0ecf47b36c6badc1fc71f1290e99d2edfa9d7cfa72446fbb32ba9c8b0
-dist/2025-02-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=f1d578e9251d95c94c20e3ee7888993ec7ea3d967a880f89963df7bea0bbe93b
-dist/2025-02-18/rust-std-beta-armebv7r-none-eabi.tar.gz=3990bce70402da79a27fd0f4adb169e4e9faf617bdbca2676bc41d9f85845dd7
-dist/2025-02-18/rust-std-beta-armebv7r-none-eabi.tar.xz=ac944400a3da94e32d7010e10b30879bbb5da456d3d54dfd0efc792884b035de
-dist/2025-02-18/rust-std-beta-armebv7r-none-eabihf.tar.gz=1196e2ae338b325ceb89edaab8b165478ec481270a7ce4c65f47f45d76e7b33b
-dist/2025-02-18/rust-std-beta-armebv7r-none-eabihf.tar.xz=fead57620d21252c958020e340fc793102d177f76fd90b3936eaf3a22a3b87c9
-dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=e5e81e1501554c2b28745c4d905bbe50f909dce3b7806f6010a9d48cc528304e
-dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=d3c9513cdb058685848de3d7864a7fa5a9b1e45f779a7ecf447ac7faae652772
-dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=6ca5598fbdbf77bcf971e62d5b3f486e25d01e95773670bdc600448f29b68a09
-dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=7e0a8798586538c4b322b58b9e1ac90e27dea4a0b5b750873f90b8ec9dcdbe2e
-dist/2025-02-18/rust-std-beta-armv7-linux-androideabi.tar.gz=cbd81d4f949248c0c48a60545648a384aa321ee5f590f52d50e8d3639a649745
-dist/2025-02-18/rust-std-beta-armv7-linux-androideabi.tar.xz=75216a970ba5a023717dbbd45b5a1a90ff9533f25deca241c11ebce80dc6229e
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=5acf37dc6035d3d83d003d70d3db3c196b20d461a70385e8e5d545be1f4392b4
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=8c75b0c815465126d6c7516883c478c78fc83cfb294bd5b9387d5bad65c9810f
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=733fca96e3d6dd232c746a6034bd7cc864f06bfce3d5da3bfd72c5ca4cea221d
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=e9ef142105d0073bf070a6de74e7173fbc09f3f22fd50eef0fea8ab6cf0ab4d7
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=13f2b55f297628bea201f3caaae0178f0d898c67a696d4b60a37c3ba5af0582b
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=455605ff7e88d69052a4b3798ba27a673807ac1be197a8ac9e57497b5bac1661
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=5b4b8eae2d86baeb470ad2a143f5d91f0dedeb225607189d9d0f8c8115e5251f
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=fd36a0f0a001436195eacdb52baee2462c43a1f9899b2e01ed60019f8285a95d
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=093900dfc07c4c4f59bd84aa8e9b505890cd8736a994798da8cfd7fb6210ab5b
-dist/2025-02-18/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=e5cef28308348a378835ced449affa965f49d9b7382d28cbf32337ae94ebc9cd
-dist/2025-02-18/rust-std-beta-armv7a-none-eabi.tar.gz=210229d27f6d574670e9406b98748869212e66713a8ad37f2e5b67ebf27e43ab
-dist/2025-02-18/rust-std-beta-armv7a-none-eabi.tar.xz=323197f1dc3fe70e0a540df8a5f5d9475dcb390f1685bef54ba355ad3b48f316
-dist/2025-02-18/rust-std-beta-armv7r-none-eabi.tar.gz=f66d3a794ea7ea0df73b5df389738e6b3e1790b27c06187de2ed1888743ecb57
-dist/2025-02-18/rust-std-beta-armv7r-none-eabi.tar.xz=ae1465d82ea49e5ed33ac95dc0ece4c8fd0ce3df20b21a6a44ed93f33d131aca
-dist/2025-02-18/rust-std-beta-armv7r-none-eabihf.tar.gz=fa0d84655bfb7488c9c378ecf833edbde08c652d25fbc9092ed2707b320f657a
-dist/2025-02-18/rust-std-beta-armv7r-none-eabihf.tar.xz=251ba3b71c4a0bbdc327a84ee1b3c3deeeed3917fe55aadff9a52a44063f6270
-dist/2025-02-18/rust-std-beta-i586-pc-windows-msvc.tar.gz=9d9d89b206dc85323a7ee765447d1cafc2fab9189be88e1558709d94c51f2298
-dist/2025-02-18/rust-std-beta-i586-pc-windows-msvc.tar.xz=b124483bdffbb41b5c806f6bcc1003ba15d031cf5fe02eaead555abe15da20a6
-dist/2025-02-18/rust-std-beta-i586-unknown-linux-gnu.tar.gz=914925fb75c45cd9939c8692b02efd337b814040ca9bce369d812b97698a4c3e
-dist/2025-02-18/rust-std-beta-i586-unknown-linux-gnu.tar.xz=eefceae8f0d42a5e3524ac134afa9a13e938f1680edf605cca2e2d9dfbd33682
-dist/2025-02-18/rust-std-beta-i586-unknown-linux-musl.tar.gz=4baafd6924c5ab59c0c4dfd30272c08328ea1f31b70e8a9a3dababb94c1dee03
-dist/2025-02-18/rust-std-beta-i586-unknown-linux-musl.tar.xz=c75b6e4b50cd731d7f955956ce0afc02f04e2adc4268a1bec8b076eb1733ad28
-dist/2025-02-18/rust-std-beta-i686-linux-android.tar.gz=e067c5483336195763c2f1e9625644075fd93cc86180e6d24bee63aa26b22e99
-dist/2025-02-18/rust-std-beta-i686-linux-android.tar.xz=d4892feae881cc914b94b8bfd66b5e75cc4d62cbb697b8faa3f29d1d70d15f5f
-dist/2025-02-18/rust-std-beta-i686-pc-windows-gnu.tar.gz=ff6f43c40e2f8edc9ca21df771c3c28ab77bcb0e254adaa09d8c9433bd56fa97
-dist/2025-02-18/rust-std-beta-i686-pc-windows-gnu.tar.xz=8d6088d7ef7f13bbf576fe238e8a032091359a773845f35e3329b5d8273d1fcc
-dist/2025-02-18/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cc62a0e5c529bb041455ed15f646e5c9c918f20a644ed7306ad8beb1abf07c1d
-dist/2025-02-18/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=9cdcd32f73d9839c5e6322f8b1e18e3abf825ddbbe9bb498616f0c058c5fb061
-dist/2025-02-18/rust-std-beta-i686-pc-windows-msvc.tar.gz=fecfb22d75b38e9c92c64790833c8ed8b4ea70c40d3d9c67a23277216c1246bb
-dist/2025-02-18/rust-std-beta-i686-pc-windows-msvc.tar.xz=a592d638118b0b95e8ef0e174b94c1825d0e3a3aab87d03737eb7415d1b32076
-dist/2025-02-18/rust-std-beta-i686-unknown-freebsd.tar.gz=e8546b2f4fe5746706d2b0d56fe174ee5993bd61a9fe451fd233236d7af0feee
-dist/2025-02-18/rust-std-beta-i686-unknown-freebsd.tar.xz=09efaf8f4f26ce6d466c1e20758901dc64348cdf390f4b878b4ee9542f50dbae
-dist/2025-02-18/rust-std-beta-i686-unknown-linux-gnu.tar.gz=e173f1ac1662deba8c719965d5d4c77e711cc0eac732d933b6c8ac021a44de5c
-dist/2025-02-18/rust-std-beta-i686-unknown-linux-gnu.tar.xz=600aa6b6ed1b49afdcc4978c897cd1e1f801193b804b0d1723319464c8378c88
-dist/2025-02-18/rust-std-beta-i686-unknown-linux-musl.tar.gz=38f7ee73e7067df2b98064b9f0ed00b8aa7c7eeae5955719fa0e2cf1f126ed19
-dist/2025-02-18/rust-std-beta-i686-unknown-linux-musl.tar.xz=6e639d9c45eda6b43ce0ce52e3213172df1875adfa0c13e52385b5aa9fa05da1
-dist/2025-02-18/rust-std-beta-i686-unknown-uefi.tar.gz=2ae2a44ad2610bbe3a97d176bbfd3e43efa22b5713c9591b9f3bcd7609f3a30b
-dist/2025-02-18/rust-std-beta-i686-unknown-uefi.tar.xz=d8fcf03e16ce9ada0253a2f8899ee9193083e1638d9e0da6cc76886b6ee14c91
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=cb0f09f7d81b1e49a761a94396dcb4e999dbbea7d70e044785992da9a2aa38e2
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=1cecfc8d91f5f3cb7bc67f49795d5e2c74638df0f7d66a3051a851522dae2860
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=0369af7a8b56dac39448a22f1ad27df42c72ccdcb43cb96e7eaecf0c0d8b94e2
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=a395fd16ea741c72b39db5d398a46a90cae8531be620a3468d0dc13f8a9979f0
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-none.tar.gz=e2ce2c57ad140b9088052009efae96ed04ce14c258cd954ee049dfc9146242a7
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-none.tar.xz=a055dd6cc47dad744fe9343d100750ea013cbe3a5bf4fcdac54e80809352a6d3
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=26f8ba1c9594f7336ad530eef0076f2d30752d2edcf96d944cc962dde3d3caff
-dist/2025-02-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=32c80782a30c7bf300510e4fa29dad76d9a40bed2d5746c4d55b17fb261d788c
-dist/2025-02-18/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=2cd25291aa0c7610f10ab04cdf4ba4d214e0c684bed73d2ef31ae84af2da0eaf
-dist/2025-02-18/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=a7f02677a5c35388593142ef95cf56ffe1632df7fd42ff35bff89dafb34a0bdf
-dist/2025-02-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=64ee7c6fb36ea45490911ae5557f6a051728a05a7c88b1476489be87456be4bb
-dist/2025-02-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=250993b5a1915a8970d91f7a10f3f50c907cc9508d71d3b2c8e20914f90254a6
-dist/2025-02-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=deb267998a725fb0288432a51aeac3004d6430fce8683c91d102b6708e5b99ea
-dist/2025-02-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=49ba80f0a2970948699b78fc60ac09f77dda94e56931399c57c2c81fce8df9e4
-dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=06ff5073e946ed2a5f80f9a5befd7b0c27e9a959cebf26b6cefc5762a0fcdb03
-dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=27f12f5835f564b03f55d85121c9474b9fc93d3084c5b5d0fc63d33c8c9dcc64
-dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=78aff087bbef054b5a6a8d2a1649dd59f69b7f98635eb0c130c4ba87b3018850
-dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=e82b6bdfed001c91f8f88f6c37e31ef35f2f25cdca6fe8adfd90d024cc068e15
-dist/2025-02-18/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=8dd6fdb684882ce4087bb96ec2d982c0d808c93c053c774b49cfc705959b4309
-dist/2025-02-18/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=4d6db36241c3d8735e7c2ee84a37ae0cfbc2fc79c6fd259ca4b74e7edb68b8f0
-dist/2025-02-18/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=32e8a2eb316b2a82f80e7268a318df89f732d7cbaba779debe10664aec7d40de
-dist/2025-02-18/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=562030f1bdc1307bc0261a2e66c12a6f21fed0ed21fdb2140b1b1d55664aab00
-dist/2025-02-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=52e8c7ab87f5d2cbb712fb54ad8394b50a7f95961e1a7e5ffce981a962899a2c
-dist/2025-02-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=74f13bf5f0ff428c323c3041771b653d3ccf5a999105869378bf09a6ce6ca040
-dist/2025-02-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=e2b8a784b4c6826d00a69de8e1891a40619f4b17c6e54c5cbed349fedefbd8f1
-dist/2025-02-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=a231848519003a9ea1306a7da2139675516c0d94e5cbd8af140bb1a37515d7fa
-dist/2025-02-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=82d33d6527db7adaff8bec04c6edb4f3f7a1609fb5e5a91011a3b48dd47af93e
-dist/2025-02-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bfe440ce80c4547afef2c6b8379bccde9f7206a5406c5a7ed5c06ab460ad8ba1
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=728c559f432bf8487c345967a2ebc9e4eada676a6d56a68ec32d26ee9775857e
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=51e7990ff209c27a15d40a684d634e5cad26d55913b897c2be6d92fcb849b7d8
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=ea66ba0e6af1fc7ce741c0838bc005abc04c6ad85c6831d2e05d04f30066281b
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=7429a295ccda168e41e9717647ba4639eceb81a73d66ad7ba01c9e7f1ca19c03
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=01824c3ca49cfb433de4508282f0395bae8053866691869fb804a3058a403b02
-dist/2025-02-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=67e324c82c6a5c9fd279b9bf5ebabaecf35374c741e5728c2db3fbbb6eab1fd9
-dist/2025-02-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=466d4e5c1912937481fbd22d739987d663f3c771ff0efd676b34fc34e9266f87
-dist/2025-02-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=409c2870098222c09abcb1c89c7394633222bef2cba9756638e8cad058e3c524
-dist/2025-02-18/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=b31e3389756f78bf680982d6c6415c3712567e5050beddae10d2df52de560e61
-dist/2025-02-18/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=729b7433746947b88b8d4f488e2831bff1a92911b8c25f16a1208542e38d5834
-dist/2025-02-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=56caed9608e88e9ed6dec56ec3265d6464633ed57b14a455c626983defc87411
-dist/2025-02-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=9c9d16cac691185cf055117d6888a25f14c72cd110e3bc699c6e78b5d0dc70d8
-dist/2025-02-18/rust-std-beta-sparcv9-sun-solaris.tar.gz=6963215ffa1d2cf9650db8bc36f1eb5c97fb4d824a010c2a65f842fa00b4b4c0
-dist/2025-02-18/rust-std-beta-sparcv9-sun-solaris.tar.xz=9077823bd323a251347336f3c656c6847d5fefb90efed0cacadd510f42afbb74
-dist/2025-02-18/rust-std-beta-thumbv6m-none-eabi.tar.gz=f6d1b17e822403428a6ddf254caf78c75c2d91c208e035590779b51d45b7e081
-dist/2025-02-18/rust-std-beta-thumbv6m-none-eabi.tar.xz=1eb4e8ca0d8a52ddf754aec64b70e7a1f91d2746eef7e3c6d4580a0794cbfae3
-dist/2025-02-18/rust-std-beta-thumbv7em-none-eabi.tar.gz=7793950c2a0016ae90ee8fb70e881047a1f85c82f087fb02532009d6419ba6a8
-dist/2025-02-18/rust-std-beta-thumbv7em-none-eabi.tar.xz=14464141719b2b2c5d4a4b29685f3a2e336c2542ea33af01cfaec2ed7511baba
-dist/2025-02-18/rust-std-beta-thumbv7em-none-eabihf.tar.gz=62612b4da1872950af31bf3d9f0a595f019e6c4074874f4cdfa9166c5ff39434
-dist/2025-02-18/rust-std-beta-thumbv7em-none-eabihf.tar.xz=07ab29714f76693f69273a5567408307186b272061501a9ac83eebe944f66d31
-dist/2025-02-18/rust-std-beta-thumbv7m-none-eabi.tar.gz=b2da60ea5d746b607c505279b84aa2a8f3bac3e258ca867f6aeca958e50691c8
-dist/2025-02-18/rust-std-beta-thumbv7m-none-eabi.tar.xz=3eee9280fdd35f30ee9b4a2e5d8614ee916f36cd08629a574f6450721a1fe05b
-dist/2025-02-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=c5be169574de4fcd550b67d19834e064b81084e673764390b9f177631f3fb0ed
-dist/2025-02-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=bcd6ddf6493cbe17236a74c26da7e16a9a752fd39ab453866ae3301cff0c8375
-dist/2025-02-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=e52c2e8272a9ff9442ae6bafb7526cac424d15d4d6d1d8d210fe981b42da9b73
-dist/2025-02-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=81adef669c6f8f08b941b0befc6af30eb78b2717c3aacd52a1526d9545548c53
-dist/2025-02-18/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=1036f47867b7d29ae468a040c50da016e20a6a3a291714df4193895234591c00
-dist/2025-02-18/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=508b4f1e307d0b033eab345ab5106eb83ad8dad212f491f1ba92b9680f699bc6
-dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=41c806851db8e59dc9ad8a756c8efde7dc14e8ef5dc4feb81be9351d267b6157
-dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f3bb9c783f4350e491fd683d057521f497314e85576b26808f4edc7d1d8612c6
-dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=36a3e0675cc972fe6f4f860da47c9d4e0ac175191622c651fbb002207506b627
-dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=c3287e3ebd4583a576f4bbdcfaa77fc21f6165b18573cbfdeb28593494ec14dc
-dist/2025-02-18/rust-std-beta-wasm32-unknown-emscripten.tar.gz=4a7128b50478a05d4fdad69715a0a7c9dcc745aab33cbc2e137cb670c6265001
-dist/2025-02-18/rust-std-beta-wasm32-unknown-emscripten.tar.xz=6e3b5981cca095c2414ad4d23f3e69a942a12c1d51dc9e055ad8409c5edbdcf9
-dist/2025-02-18/rust-std-beta-wasm32-unknown-unknown.tar.gz=3b0cbbb35daf13711e8f211da8e2ed4ade96f728be5e5ad3ca02e4d3e32b7262
-dist/2025-02-18/rust-std-beta-wasm32-unknown-unknown.tar.xz=4e50db69d0917f205a16fa3c4ee5e4012c000194ff75641ddeb49bbec9a2ec49
-dist/2025-02-18/rust-std-beta-wasm32-wasip1.tar.gz=d382d7f9787018480329518035fc4ce3247775633423e0f2940c3670cbdd4705
-dist/2025-02-18/rust-std-beta-wasm32-wasip1.tar.xz=e1d9c800db62bf606d9be9a75dd00ac7190acf3fd3592cbdeba67170ddb092aa
-dist/2025-02-18/rust-std-beta-wasm32-wasip1-threads.tar.gz=cc7cd664a483eace96710d341132de4f9cf2113f358722425ddcf84cfe821116
-dist/2025-02-18/rust-std-beta-wasm32-wasip1-threads.tar.xz=17156e3e57e304ab3ab10f8191a9952400182d2a46ebcd39d1cfde97b94c0756
-dist/2025-02-18/rust-std-beta-wasm32-wasip2.tar.gz=7ab89b39693bd1bc3f344dce6ad1c127ef38f64591c7be769d07603b2422800d
-dist/2025-02-18/rust-std-beta-wasm32-wasip2.tar.xz=2f53c60d0c0388ff644c17e341368e8b15d4c41b2827b03507d4efee100a1841
-dist/2025-02-18/rust-std-beta-wasm32v1-none.tar.gz=3277ec65149e708925ca7fc062cde92953d01569d2700d2831e6ff68768e5b30
-dist/2025-02-18/rust-std-beta-wasm32v1-none.tar.xz=24df037c2c4bcb3d593033d93b6e26aa1dc38161452220d7a73a23a696dc93bc
-dist/2025-02-18/rust-std-beta-x86_64-apple-darwin.tar.gz=3878e1506ee4642fdd1bd5e10025c9c289f8d03b7cea876d2348fabc2675b721
-dist/2025-02-18/rust-std-beta-x86_64-apple-darwin.tar.xz=46bdd522559b61848cfcbc8c55d95b190a134f2a0ac19e3c7ebfaea867f9780b
-dist/2025-02-18/rust-std-beta-x86_64-apple-ios.tar.gz=e914a0a4a2824f12764b0b91b0dd97a25416686839f35dea2aabde41c011f850
-dist/2025-02-18/rust-std-beta-x86_64-apple-ios.tar.xz=b44ac0cc8cab86ba9d000d2164786b5bdc115ace7990ead57aaba2b0e02750aa
-dist/2025-02-18/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=497c75ec8b5f99a625d898b406d437b8902b8ad42ee1d629a0efd27cfee96e44
-dist/2025-02-18/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=a53ed7bfd16d62a7f51509d32fb6cc6b1f3af331f4c4867cbc1eb57da5c3d521
-dist/2025-02-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=3cec5b6714f156e43c85b4b15377475bc38f65325f61de020bddfc2708b25a7b
-dist/2025-02-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=ea2cc73a03644647dec905100154a3238dd819fd0421f770dbc433cd6dc49f33
-dist/2025-02-18/rust-std-beta-x86_64-linux-android.tar.gz=2eaebfe572503b69e34674ed414357c514bcfbf013e6a2a7bb3fb14f501872e8
-dist/2025-02-18/rust-std-beta-x86_64-linux-android.tar.xz=66c4f03b907515831f9a48c8f5036d4c3115e814507a27abe1e423ef4a7e7c0b
-dist/2025-02-18/rust-std-beta-x86_64-pc-solaris.tar.gz=4c8f54f1709908a9edabd9e60d8492cda771db4b51fe766f2a2323a10f184e1e
-dist/2025-02-18/rust-std-beta-x86_64-pc-solaris.tar.xz=60d74169e80b3e1297b010501fa5a46a29a7541c84ceeff304b4c2ace7631540
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=9d043fbcd7e180052b903180114d50c71a2ccbeb22fff7020514b4b0a11a8123
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=f08905c0b8192f23f214465d757d93e30aee0250dda279d648e948961e0745ca
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=e35a42a9a6eccc4b738b389fdff24ba01ef23ff8d00fbd34100acafffb9c3763
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=a1fd2d1b1bb1fe9593df7835b5fb81e5c9453c0bbbc17b9ee5deb0512ad12550
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=feada263ce77cd0ec635ae78c8ce34099385a1f89d1eb680576a85a8adf0d75e
-dist/2025-02-18/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=ee8def01984eba376773f7a055a18a4096750d26f96ab9150326dc60ece9fbe5
-dist/2025-02-18/rust-std-beta-x86_64-unknown-freebsd.tar.gz=7791a0155a0a3464d07b176383a4b61dcfaef4bf0247c58d447402fac3123186
-dist/2025-02-18/rust-std-beta-x86_64-unknown-freebsd.tar.xz=11bae401884cce0306b415bb1202c2c63f81395677057fbbe12e9302951a9d3d
-dist/2025-02-18/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=4d05cd943f4e4250d50a5f732a64f32431a6cfef59b38bc087b1dbe1aa4b9561
-dist/2025-02-18/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=7bdc7161d66b6c330f027f53b15f164c9ad4d55debe77b7c34971a877bf82caa
-dist/2025-02-18/rust-std-beta-x86_64-unknown-illumos.tar.gz=01edf8fdab00df25cfea2ade367dc4f66a1d08d11bfd9a7e56b65a723e14b517
-dist/2025-02-18/rust-std-beta-x86_64-unknown-illumos.tar.xz=9efccf8ba6fc68997123924cddd7008b15f1a57170d03597a370346fdc6c83d6
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=9dbfabe77853e672d576e70332e07727882cd6af14dee9a00d5186b43763ce82
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=04e31482a3ff18d8fdff40c4e95b22bc667bc0dd1ba06fadbe2479bae5d97288
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ebb6e0c56d905ef064fa15449a72746daa9e3998f5aba5c6a3c132bc676228cd
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=818fc179c8380f0fb70c46e04086926a69b026591ab62cfbc1051abc5c80012a
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=c0a1c692a334821d61a9b92cd1332f047175d4335336db3e2129687ba96ce5bc
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=2c71b87db4cec49e3c620e6b4e0e07f1aaaffe69020b07c87546232ed1ad3b20
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=c1bbf445dd0b187904af5871bf48a720151ef75fdd3dd13161dad01ef5e87bbc
-dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=19963165ec2c35c15024869c16a707bdc90e72032ebf6e203cc67411ec8ba7c7
-dist/2025-02-18/rust-std-beta-x86_64-unknown-netbsd.tar.gz=63fbbd51047125fe30f1954ea19a05d6f051d2a77929952bab326c8ded6db8d3
-dist/2025-02-18/rust-std-beta-x86_64-unknown-netbsd.tar.xz=1c255d1de9c2629210575b862600bf369499a0eb8873178ceff4a337ba9dccfe
-dist/2025-02-18/rust-std-beta-x86_64-unknown-none.tar.gz=781f14a54c5e68acde1e68042905a48f687294e2bc61450f422a6e15bf6ab509
-dist/2025-02-18/rust-std-beta-x86_64-unknown-none.tar.xz=d45921b98740f3cce5833bc4fb1e36816f34b81e96c3ca2c76deff4744134c6c
-dist/2025-02-18/rust-std-beta-x86_64-unknown-redox.tar.gz=0cd76d3c5b051b0b2015cb08079ea3b5ecbb9b0b68779eb35946721b24c07008
-dist/2025-02-18/rust-std-beta-x86_64-unknown-redox.tar.xz=6dec719cdb7f35f6eafd901414525b40f030566bdf3fb55e3b05de162dbf0741
-dist/2025-02-18/rust-std-beta-x86_64-unknown-uefi.tar.gz=aad1e2cfd4f428acb67d9dac1fab4450eccfe9212f52f99f06c09899285b6b1e
-dist/2025-02-18/rust-std-beta-x86_64-unknown-uefi.tar.xz=4252b618ffc906949756ad28a5437d11b0353fe1d755ee1d23502a208bdee74c
-dist/2025-02-18/cargo-beta-aarch64-apple-darwin.tar.gz=2f7f459d2595d3f60bcef4ccbd3c72095a3ec54fa3f2221a647ae892c308d5b2
-dist/2025-02-18/cargo-beta-aarch64-apple-darwin.tar.xz=501feb9138f3c11a13fd649d6573924ead10f5e6fb1e759d880684bff11c12be
-dist/2025-02-18/cargo-beta-aarch64-pc-windows-msvc.tar.gz=b589177b0287a42ce17939dbbee92d883dfec88ebad33bf9a719a3cb2f446533
-dist/2025-02-18/cargo-beta-aarch64-pc-windows-msvc.tar.xz=d795082d304ecdde233a4b6bb3aa558392b2c5a1553fab213ee99648c49f7a51
-dist/2025-02-18/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=8444d938514ad2d55769cf614774dfb4e5a27c34f8ba8b49329a2bcf0b000162
-dist/2025-02-18/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=02e52fc13ae52066031ac40dad039ad752b83582e5f9e74ecef206aa9206ac16
-dist/2025-02-18/cargo-beta-aarch64-unknown-linux-musl.tar.gz=e89709bb552e7ee73de02b08c6d8820b07bccdc09777eff9716efabb2bdd50cd
-dist/2025-02-18/cargo-beta-aarch64-unknown-linux-musl.tar.xz=50944f0e51190f9db065764afc7a41a3a1e39767bd1ef5ec659c98fe9243cc98
-dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=0343dfc2f015d476b3aca59b33dd75f907f595bc24715e6c518194ab1a5dfec1
-dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=3dd6c378c10172b1abfdd1db2fa764d1b48153ac1b5065cf124399941d036e56
-dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6eac5ffb9adaf2591d3b1872249f4a959c04afdf6694e62dc850936aa8d35972
-dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=484510e6b9519c2b047864584253c8c1f725ce843e8dd3117349032314737462
-dist/2025-02-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=fcf4d4b2d401ea689ee32f38b4a61c77b52ff4d3d114b23d0262bd02c3d1ab5d
-dist/2025-02-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=1a75296c42d6cf93a5e51ecb2b2bfbf0cdea350668d610e8b0c90937163b4f33
-dist/2025-02-18/cargo-beta-i686-pc-windows-gnu.tar.gz=d1b5147ec79466ab9441825b4761e89cebe57ad21a3199b0eca0779683c45ed6
-dist/2025-02-18/cargo-beta-i686-pc-windows-gnu.tar.xz=980850e06ccd90512baebbfe3baaa65b5c089edbae8146fd940c708fd7556abc
-dist/2025-02-18/cargo-beta-i686-pc-windows-msvc.tar.gz=78c67ba481cc7b855b54a2edc0297bfb5eadcd83d5a028b05291415417bc6947
-dist/2025-02-18/cargo-beta-i686-pc-windows-msvc.tar.xz=6ea74c750e6e0a794965c6616e5b1a82dee295815b0c24a3898952b1a5a02c8a
-dist/2025-02-18/cargo-beta-i686-unknown-linux-gnu.tar.gz=a0c8f67fe77b94674698b4816c081e2ef08500990c0f9eb069d0190df9c4f129
-dist/2025-02-18/cargo-beta-i686-unknown-linux-gnu.tar.xz=9b13f958ec4edff194858e90c54866a129e88769a76fe22582b07e17540708c3
-dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=f4d2f1c8a7bec6d2b8378aa87a324c42f0f414962174b40b6f0d1dc21d0cacf4
-dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=f25659ef3be1a28da8821eb178e02108f41cd5c0b87aa01a052a3a90e7a9da50
-dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=b687a7c3fac08680818804e034af6689f1bbcf8fc0e406c99b2a49ddae1e900d
-dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=e33818d2f94e8ba148dbf8cd53d6396e370157acba6d0865a5ac71d292939a0a
-dist/2025-02-18/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=9cdc2115bd2022cb0b0ac4f1c71142c064957137decc028dde7585acabb8b780
-dist/2025-02-18/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=f722447494f0a7af9c31b71364aa4a2fde79a9887440d8281e4561f7d71620d3
-dist/2025-02-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=d8a30f9e48e89cb1d18532fd7fbef8eeceef6bc602ffaf9e730c635e2fdbb156
-dist/2025-02-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=ec6b3b1595c5761b8092a04a412e79534c28910ed78ed792c9af7ddc4d92a389
-dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=4bf9c73173199fd3ca952d33702288deb483c7fd392179352135b64e7e8fadb4
-dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=12aa06644e07344a77d0c16dc1ed96bfba63de02df1f432d57b82f8a1e2282b6
-dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=eab362146d449dcdd10740c8e6f9dec6e640ffcca162eb51febbc835e34acdfd
-dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=867b716eae9225c66c0ab4642e4e497055ad2effd24343bdf80354ce2845d6f9
-dist/2025-02-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=0503ba2e4b1d668fa3a3174f96ec3fcc12ff767574a7af8ef5fc824ca86dc965
-dist/2025-02-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=478b9f1d4f517f93f15530d27a7d55ea29cdd06eccf01176ffd08c0ee3204c1f
-dist/2025-02-18/cargo-beta-s390x-unknown-linux-gnu.tar.gz=419a679aaf6e164649538916daf28081a063bd56c7b86ff0e2df58072f334fdc
-dist/2025-02-18/cargo-beta-s390x-unknown-linux-gnu.tar.xz=31b39e242035036c1101412b7c86387e1183063ff5f6ce67d311d0764435a588
-dist/2025-02-18/cargo-beta-x86_64-apple-darwin.tar.gz=d6d5224228dd54b6d16be30271111620c02fd88e656b8bbd22452b66b0d5cb56
-dist/2025-02-18/cargo-beta-x86_64-apple-darwin.tar.xz=cbeff7c031b4ab4732207b90ee8849b27f03cb28d3e085bf4d70444347dbfc99
-dist/2025-02-18/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ae5922955ec579732aacd8112bc53bf5333438eb81d0f81dc5f387888ac979a3
-dist/2025-02-18/cargo-beta-x86_64-pc-windows-gnu.tar.xz=553c55a2bc8eae2c8ba831823a97f2232808af1f753642ec4cdd09c33dd3f6ae
-dist/2025-02-18/cargo-beta-x86_64-pc-windows-msvc.tar.gz=d9b2cf14565478429fba6266f0c86a58f3bbd1ce11a63268828b33ccb55759cf
-dist/2025-02-18/cargo-beta-x86_64-pc-windows-msvc.tar.xz=2e8c0560355d11a038219072d2503860f5c5b3cd137b89ad931f54d9bba60499
-dist/2025-02-18/cargo-beta-x86_64-unknown-freebsd.tar.gz=4b528361607845e6f8ece403bbdb8d77c6159ec137396319562ea2772502792f
-dist/2025-02-18/cargo-beta-x86_64-unknown-freebsd.tar.xz=c244ec4f97420c29c690e32bd6d8f14994bf1d990747f31a3dc0f2b37644493e
-dist/2025-02-18/cargo-beta-x86_64-unknown-illumos.tar.gz=7d3b49df93e87322a9e99e36c6df020d3311c5538ad2298d8b5d8f2d9ad3e0d3
-dist/2025-02-18/cargo-beta-x86_64-unknown-illumos.tar.xz=136ce90487448ee770472d4bd2c0d9c96200f0ec762419feb42fefa26ba36b58
-dist/2025-02-18/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=510538965ea142405925d3f4f03a87783516407989b8aa7be07fb84c0680e9fa
-dist/2025-02-18/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=a8c569398d71cab0b90c809b1d869a2e3c5037407b5af804df08c205775981c2
-dist/2025-02-18/cargo-beta-x86_64-unknown-linux-musl.tar.gz=1493f66e5cb12e8b955841804e7df745e26daea2278144aa57670192c4c62cef
-dist/2025-02-18/cargo-beta-x86_64-unknown-linux-musl.tar.xz=472bbe49415557b75b572879d0c33750731c1fe9e56cc6ef3b0fd5532e56446c
-dist/2025-02-18/cargo-beta-x86_64-unknown-netbsd.tar.gz=d3baa6019e13449c01fbeebebce42027ce4ba70841cf28733f6849e7c6ce5d89
-dist/2025-02-18/cargo-beta-x86_64-unknown-netbsd.tar.xz=0db9af42e9ad914a99db4924721c895cdf490bc5351bc8c2d8993e3569e952e4
-dist/2025-02-18/clippy-beta-aarch64-apple-darwin.tar.gz=6ce3b464744082131c99a213454225e5702564c83032e11dd0f3d95530a4e0af
-dist/2025-02-18/clippy-beta-aarch64-apple-darwin.tar.xz=925baff0d91b959a99c989a4ada70973baf3da03e1d7e7e8be1fa334c3acbc50
-dist/2025-02-18/clippy-beta-aarch64-pc-windows-msvc.tar.gz=76d265c2fb6280eb8ed399501964f301a50e09e548cee708ebacc978d8db538c
-dist/2025-02-18/clippy-beta-aarch64-pc-windows-msvc.tar.xz=e3d1d69cbc838ab639b2e41537b10266f1b6998a228882d4041f35cbb8984909
-dist/2025-02-18/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=918191cad727d795b51f892abb6e4fc87ed735bfcb51433cfb4371cb8be8690c
-dist/2025-02-18/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=157d6eb9e7dd80dda7daae5584d095a5e68d13ba8b1d1229e90b5b51f6670e8d
-dist/2025-02-18/clippy-beta-aarch64-unknown-linux-musl.tar.gz=fd4de290450e3d3c9188263d9506167e298f4c2d4c781fb3573806694b5ca1ba
-dist/2025-02-18/clippy-beta-aarch64-unknown-linux-musl.tar.xz=335c5fd24d1c118e4d1d8abc43d3529dafc9b30af39f6b009924cd0fea676182
-dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=209cdd2042e293d1061b149d97333515821dda0ffeb9b30f24dd2dbb4c1ad548
-dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=57dbfdc34ff4e74aaa8776b80d35aaf0317fdc314ee4b0f3bf58fc672963cf38
-dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=a89a2562fe9ac6492a5de220c395f433b0e53a8b29c72b3a8d4843f996649ca6
-dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=0e6ff6453df1397e7b12e7e356e7c7300cfb1f85bc3a6705735067128d2a8135
-dist/2025-02-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=7764c2dbaf217f4b1d8ca4ed2ceaacbb91e8010d26ae1bb10b808afd5dc6a798
-dist/2025-02-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=b7a042eb6830653a623c6299ef57492ae6c9b51a9cd8480f0a6fc2fb6d378bbb
-dist/2025-02-18/clippy-beta-i686-pc-windows-gnu.tar.gz=ff41e5b666b3531ccdc0ee836dceb270179d6a849e47024eedc6ea309d36791a
-dist/2025-02-18/clippy-beta-i686-pc-windows-gnu.tar.xz=98c6386b63ed89dd96beea223f4c720320b6ca460f11b77c46427e128034cbbb
-dist/2025-02-18/clippy-beta-i686-pc-windows-msvc.tar.gz=12bd371402e4d3251f60fa29b3b3aca88b4480229088b68791dffbb4ae1554ce
-dist/2025-02-18/clippy-beta-i686-pc-windows-msvc.tar.xz=62a22d1e9b4fdba254e549f5edb276bef5252754ba67a76526d5aeca85515646
-dist/2025-02-18/clippy-beta-i686-unknown-linux-gnu.tar.gz=04179b3a20a68ae2fd8444832ea4edd8155dc9296c7a1edf101053e3ff934891
-dist/2025-02-18/clippy-beta-i686-unknown-linux-gnu.tar.xz=c955e464e99097025fc7d0e42bf90342f74f475c5148526df2f51ca46ce8db4d
-dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=6f58d326a1f2a35246384640b999f95a961a9fe1e5a3c4a3e67d7f96e1ef43fb
-dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=583b1d55a38fdd473a3f3f3cc0fbeac808fbeb593b8b45c7a6b8a09dec0d68cf
-dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=80d73fe94ecbbcdb14b35e1616d52e0bb9b1f04dcdd4fc384e7103cc36325014
-dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=1bae908e4d3931eb4dc71ac1524f990bbccaadd9d30897bf516899baebd4c5d5
-dist/2025-02-18/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=b882e7ea97e0d36b289a46ef84b14b2b44ccea93ebdc77b2ab3430361ad15b1f
-dist/2025-02-18/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=91e52dc398dccbafd040e401f155c204f2a14d5f62aecfc24912910d5e45008d
-dist/2025-02-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=c81497f2b2d2670b9dea2e35804e10780c1631a8761d4bc3331767c1ccaad6b9
-dist/2025-02-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=6236e129f3e551a3126fa07662cc8ad512ad5fcf436a8da9e27a915ad4c234cf
-dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=1b031f055ea4ab4a9da0c8bfb0037e92b493caf7879351f8b404a96c447ec92c
-dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=2f07224e49f7cab10d673116d9dee9f964b4c44ac3db336e7ddbab9e0b1bc698
-dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=84a8295a7066d258404c87d2269a01d89cc7efd0f143ab53689597f3fb351417
-dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=019460a6b0e1c5c1331d5a54f3e45306ba0d1b1c2206e2e69f38c1c3501cf741
-dist/2025-02-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=aba8f7bd0a89205961f9803418cdf9bb63a7d72bab4a1ff937f4a142921f4833
-dist/2025-02-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=4607503ba131ca655dab86ad48c1737f216f8ec25ba6dfddbf1f0807e5a6dd2a
-dist/2025-02-18/clippy-beta-s390x-unknown-linux-gnu.tar.gz=b0170f9b9e13d4f6e016124fd40c858e00155479fb4f96c1edc896130bb76dcd
-dist/2025-02-18/clippy-beta-s390x-unknown-linux-gnu.tar.xz=397f0a8944beffb87c74717bd0f422836b3daccfa848d91c0a65875031bf12fa
-dist/2025-02-18/clippy-beta-x86_64-apple-darwin.tar.gz=11be90b9b09f4e24e56df2a602ed8161023314514121d9f76e424fb628df468c
-dist/2025-02-18/clippy-beta-x86_64-apple-darwin.tar.xz=16d313798f12d0e74f888b627e079606958de58eb2ca4c70d5f7de8cce72620c
-dist/2025-02-18/clippy-beta-x86_64-pc-windows-gnu.tar.gz=41ed081e4a7b205cde3fe958db18ffe1c1ac5a9c336f965a03fe89499a3eddbd
-dist/2025-02-18/clippy-beta-x86_64-pc-windows-gnu.tar.xz=daaa3267dcbb3daa0cae47861683f29da5b7419214ec5949e242aa93e3f87148
-dist/2025-02-18/clippy-beta-x86_64-pc-windows-msvc.tar.gz=6d9b8f549e34d8fb65987b39c01c27fbb0e18e8950a07ec6fd1888d01e253971
-dist/2025-02-18/clippy-beta-x86_64-pc-windows-msvc.tar.xz=1c26b51c484f5b10ee693212e258fb86c63a2b59e631542918799d480a3587d4
-dist/2025-02-18/clippy-beta-x86_64-unknown-freebsd.tar.gz=a42777c542773a4262ac9fcb07ed13f769957f58a795160441241ad4e4f5258a
-dist/2025-02-18/clippy-beta-x86_64-unknown-freebsd.tar.xz=9e809fa141ac68557f203aec2a6cc02a4ddd22169595c40ed4a964801ccadb1d
-dist/2025-02-18/clippy-beta-x86_64-unknown-illumos.tar.gz=4e65b5db249a18e73247029506f619393be7042f2c91a00301962effb76a18ea
-dist/2025-02-18/clippy-beta-x86_64-unknown-illumos.tar.xz=6714018d069fbce271c177f1941a6b77f18b67af462596aff273f7db1970ef4a
-dist/2025-02-18/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=72a8ee3bad3d638af0cc3ba6c0c0ed1594abe609573de71d9c7a884a8ac7645c
-dist/2025-02-18/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=f622befd60c3695d3d62642b953deabc3e3f04b32cae8a7cc228cb534244adbc
-dist/2025-02-18/clippy-beta-x86_64-unknown-linux-musl.tar.gz=8946e02ab98281b6949c4d725a5fe3fb1bfc86651a675e451f126fec8d053762
-dist/2025-02-18/clippy-beta-x86_64-unknown-linux-musl.tar.xz=425907bd4320c516647e5dd6df6154746d64854fe2e78f27283b7fcb27164de7
-dist/2025-02-18/clippy-beta-x86_64-unknown-netbsd.tar.gz=505208d2d73ed7278e5b29d8450c382a89e4c0992d6199243e07c8640c611b85
-dist/2025-02-18/clippy-beta-x86_64-unknown-netbsd.tar.xz=d4b0306e7d7db5cb7da977a7ca72fff2070f102ac385c3b35286da25033582af
-dist/2025-02-18/rustfmt-nightly-aarch64-apple-darwin.tar.gz=13854358645915af29d9337bb87301aa1a5e76ecc86a934dd640d02af3255ea2
-dist/2025-02-18/rustfmt-nightly-aarch64-apple-darwin.tar.xz=0cd190bd5a064235f9cd6f6e7eae4725b3b53ae36493b3ea54b8f190372ba3ee
-dist/2025-02-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=20b3f8c4c7b02158181970804d419b16f85a1083943e1c384e0bcef441f32aff
-dist/2025-02-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=1ace0f10060d2fc35a1f05a1d61adebf95212e8b46a2234c2e78030481c1b3e9
-dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=e5ad64d67931df49f6b7d3448e9860699d6549c2b4a96abda1a03069b45f339b
-dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=e8112ae80c8fd43452612b79dabf471be561b7e828c9a2141c698429d761a49b
-dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=8ad36bbe888e61b6d7e540ba4a2478652f14c1b28dbbcaab732003293b7c985b
-dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=1794af320a273f4a951942ff0cd73a359fd82a971c572af1ab7ff2961340791c
-dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=67b9d1d3c46bcce0aa94d6cb4155cdf7376677caf2e19685553266f781eb7cc1
-dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=9d7b97a85b1368cfc78f1df42afb08aa04eb17fbb91ceb3c379d59fab4294890
-dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=42396c7bd206d0fa07f3b44fcb894ac074e2af07eb158c1ef630bb5467151c8f
-dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6881c9681342f1430fd9cc8c9786cee40522be3dcd0fc4dcf2b3957d9d53f03e
-dist/2025-02-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=6cb8973ac4215d67aad9bb56521024626d7883a6e00748623a728dd9107698db
-dist/2025-02-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=920d877e04260be6ccf9963bea12220e886df673cbc48b55925650f8f5b21d9f
-dist/2025-02-18/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=ec5c7105f2c2a2055f704435fff9edbbee0a234e63050676c034f983d4e341ee
-dist/2025-02-18/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ab408b64db4bd47abf8e24c0f611f2c67a3c9ce7e2138a92772e0510c6dce5f9
-dist/2025-02-18/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=d04250bc2e57fcb03f1d80722f2ac1117f797d768262d7630c9b53af808a8c9d
-dist/2025-02-18/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=6d7be9f04a46040f068544e32eb84c98afc1f81b750beb229def84a7513150fb
-dist/2025-02-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=94f585a7c666dc9c95c3ae14744e614a3fbe37b3e31b476b48bc4ef3289bdd46
-dist/2025-02-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=83e82932245b3c1d3c275126184f942b9cb8bf20f0d40c7cb1efb6f918327b9d
-dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=9c8cb5a14294c48f8ee972d5f460751a8bae5b541bff3d872c85812b621c39d8
-dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=4f616740bef30599e6950ae2d8ae694513003e14122f6002a9d60bdc64f77cfc
-dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=a668e7be7946f6a9099486a40256f17832288322c9237d931f172ed76caf678d
-dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=b02c57c217f358ff4344ee2afcbb8353cffc0a012f970d9520ad233d188d59e2
-dist/2025-02-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9baf04e268999020372b21484ecc4f5aa001b3bcee05619ae5b0a11571a3a45f
-dist/2025-02-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=b2c2c3a0eecca7b4c35eabf09e215158c48eb426899e365db1c91c1c560ad255
-dist/2025-02-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=c42df8e575a24a5edbc58b5b46a89a226188d2aafc59da89d568acbb6e9cceb6
-dist/2025-02-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=fee7c373bb8fee5c7d4e43d7a7046d3bb156d3e496ed21cddf20c21ffdef3e69
-dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=a0ae21a3b56e20e667c72d92ad4bacd4abb77d1fea32949d7dd62a56d6b531d3
-dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=fc7e21cbd61169b37e81c73d4d5353d7e54ca322fd01491d9f37ff3666557e7e
-dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=e08ceaa9241c2e53041b107af09674ca4fbc4e12b1371254869e3d80d5c907ab
-dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=9f208dc6e5938a128174263349345e9fe7f587689f6a53fe5d026ae3c6fbed2c
-dist/2025-02-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=44abe49dfc0492cb3ab28f0aae0d784c982063399a38f8f13016f3dde123948a
-dist/2025-02-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=72fa294f92ab244608c384d6ad6eea0e540e6fc58181fd65a4fce0c5029c39fd
-dist/2025-02-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=556dcf393856c6d9c9c6731b02e34146f9f956f588025b6a614b8802032d125a
-dist/2025-02-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=93906364910891f71e13e0ecb07f02b707e42e11a0f1b117c590804dfa16a9d1
-dist/2025-02-18/rustfmt-nightly-x86_64-apple-darwin.tar.gz=7022c760f457075fb353e59984dcb551600581a315fd17ea1320b892b1d99a55
-dist/2025-02-18/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e085ee261acbaa41361a0263dd8f13644f8a4e3679eca6bb0851b03c647b80e8
-dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2436e18fefae02554e620a1131455d923c1b67e00e878c75a941a6eedb4eae28
-dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=9f6e37b5973925d07115e517e6a3e490a221218f48fd101a20670da2c3d01add
-dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=78f492a26981e7a6f9f3e8bbd1e880682e55cede081f3cfb13a2ec5f736edbb2
-dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=d4d788fa3e3b9a598aa7baec47af3b56362224533be85dd68a411f35f8800b2d
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=8922186dedf0b12e9aa2bb041b76be8fccd43b9322c3496c688355f34bbd7a59
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=6325e43f2c28118a9525f5c5fc09de9fb9a09ffb4aaad31f28d394c233ee8398
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=7f317107f8319c650973cef52f745c2a8e57ea6a087910b6979404f2cb2f1cff
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=b273be4897e83f786020bce1dc5dd1caf01e2ea43f085391c0031277718feba0
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=0373011266a9ab62f45fa137a4bfdb970ccad8bbbb74bf776466d203f28d226b
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=62748525678370dbda7f1cbd12a384e95d4af76103de998785278f6d1f076177
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=30eeb980720d8c22bc45c012c4fd212e118195206b8b993630f074e526e6693a
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=2f3843d9544fa56dc87f1d13ef79c68c1e68d84bec007f0345159a7448368dfe
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=a86eaeab8f5f45d16eaf355a46d8b19afcd8c46db732432091156e381aa79cb6
-dist/2025-02-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=144cd28da601c331f6501c634ad89286be213a69cf521435e35657c5f6fe2afd
-dist/2025-02-18/rustc-nightly-aarch64-apple-darwin.tar.gz=21101db859a550ab39de1ecdec75f4f058934ed8e0ab7dfadbb2efab57bc5e0a
-dist/2025-02-18/rustc-nightly-aarch64-apple-darwin.tar.xz=a40da26e908810701112b9d3f9ab83515c8e2f4b33219f8f773c5459366d37e1
-dist/2025-02-18/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=5391bc993b7208c10a6f4256417c9f76a4a33d167b2fd547b57af614d3fc8458
-dist/2025-02-18/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=d72a205f52173b1726d8341a9436e62439b1987fe0cd4d2bbff740e38f629b41
-dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=185e052bf2ba1cda4b6ad1c49a9f65b906899ad1ca09cd864d6041941ad344dc
-dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=640f7af3fef5f0abacdaa292ce17255433ee16f12bfc2d2e81d70afcf9fcdd8f
-dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=8cdee468a90606b21a8cc3305f2b6b3eb7e3d687263f4ca8319c709cda2a324f
-dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=358bbfb24816c781e07d5480a5606dce27068f856c0a606873ceba05c9540c3c
-dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=b220757cc8ed39c429c49b55e293ded3e07239d2e2bab8a9054ce55581393c47
-dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=18d3cbc49e44b7810b498517d21390e39bee7ca8351c8b321592e83301ad79e9
-dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=77ac127bae48859f57d9bd8337ac4a0bda95b1190e451abeaf7e77f1a240a647
-dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=79009bbf0325f9db0c905d74cb0f139c92478a0b2fb5edaf383366b0e654a172
-dist/2025-02-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=8264c7ed7bc47953ae76cf87236655562a55846abb195bc9281833a0da168db6
-dist/2025-02-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c6a85e7f2a469fb05f0a84ceaea25dc0d95b57bd4d68dcee447918162cb36b2a
-dist/2025-02-18/rustc-nightly-i686-pc-windows-gnu.tar.gz=0f31c9ed4ba7e942806fc2927d305f9d3ad676cf81e53e0f7c4123aef375fedc
-dist/2025-02-18/rustc-nightly-i686-pc-windows-gnu.tar.xz=350f4b46dee2aa6ebfc31912cfae5c7c1db99b298c52834308e95c504cadbe7d
-dist/2025-02-18/rustc-nightly-i686-pc-windows-msvc.tar.gz=e12a40b7178995ac223eb7fa317e1114a988256d99fe615f70d64cf3f2891fa7
-dist/2025-02-18/rustc-nightly-i686-pc-windows-msvc.tar.xz=09fb4a4744a55bf8fd6371e5496f6a9c00b119ddf20b19855653d66d9a618214
-dist/2025-02-18/rustc-nightly-i686-unknown-linux-gnu.tar.gz=52361a34730f8bf14eefad7e51f66fc3ba3be405a364d4520103208fe8fdc056
-dist/2025-02-18/rustc-nightly-i686-unknown-linux-gnu.tar.xz=ea81964fc8bcb8b43968acb6a4f7fdec2ddea9f75a8be5446fb01b4267d0d75f
-dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=11e7a143112b6abf818652e425b6f092464cc9d8f5286e90180c7af8d5939643
-dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=86f5d40eecccb623ff744bbc1fb40458949db9b2f8501cadc6be9bca95f6c693
-dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=1be7ecdf609958fb0ef945203b22a600f1e343ee7fc581f6451eecd39f1e0b7e
-dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=03d3b67092da64f7b7be7ba4e115cfad4071c0bea3abb5e60ac166127713b169
-dist/2025-02-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=4e33311490c2dcf79a16307e1141ce37574ec3829a1e93d0f5b06ff68ad5c861
-dist/2025-02-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=504c102fa1c8dc5042cb354a60b87c0f6d47f9adab341f496af723f3ea8bd548
-dist/2025-02-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=c559971ae42a5e0e999e2fe119033bffbfe8c64b767e697e0b95f5dfc271d13e
-dist/2025-02-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=51159ab0ade5a62e128b6c794da5c9815324470c468e5808b50663c3a0df6d39
-dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=a8134f8f7ea4531d54ab5c0a0894f140ce5182a384c57395edbe06ed551970ab
-dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=8f2f5d88ba9f4ee946db5f00d56c4852213dcb0b46ce2793966af6c96d934dc6
-dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=7bfc6666757b57fa6160d076a9eb52852dcb5bf788bd12c0f014bbd552b8a7ef
-dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=e2c3293e2a90012ad48bbc2b6f285adf20f356ff1f4146b3f11543511bbb3c44
-dist/2025-02-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=f582a59b5a6cbe6d58400c69f1cad4f34d0f1541c1ffb9df3ce71846edd828fe
-dist/2025-02-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=244384bd94f7c3606a086abc8be9d36a855faf09d9bb6b121f42e168c526e717
-dist/2025-02-18/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=327e29662140cb76b1ff362fe51f9a12fb4ec304929317ed8de7295fdb9c5b9f
-dist/2025-02-18/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=a2c4e19b3a8dabd5c8fe72edd60d1925947cad5971c77c62f12fca764c6e4e7a
-dist/2025-02-18/rustc-nightly-x86_64-apple-darwin.tar.gz=b6812f92e08cff1b706380637fdd553b04b9cea746ffb69e6488fbec70680136
-dist/2025-02-18/rustc-nightly-x86_64-apple-darwin.tar.xz=f2502b2a810938c41e2302a9112c97d04998ada16583373e6488bcca00595761
-dist/2025-02-18/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=9159f7323718c6a8b98f7de5186ed507b3dca1bfcce9bdfa6437313bd630a989
-dist/2025-02-18/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=10d54c9b80570b6729d0e68f017d862c5126f09b42f150d004aa8fd5382b165c
-dist/2025-02-18/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=1f29c1aef1dcc3ff9f2e3013b7ea0521829e6e474f9058cb70fea65180230b41
-dist/2025-02-18/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=18cddaf7653f146dcc8a44ca0cc33c6dd3c24f28fff87aedca01fe3beaaa9915
-dist/2025-02-18/rustc-nightly-x86_64-unknown-freebsd.tar.gz=e57c1477cf9b75e727db48b8b75435d65aa0a6ef0eb566ac1890b576c330f64f
-dist/2025-02-18/rustc-nightly-x86_64-unknown-freebsd.tar.xz=725f9e9d25b7ad6f60d5596684964b0c3a63d98a62a2aeda6a134b9f02fdb681
-dist/2025-02-18/rustc-nightly-x86_64-unknown-illumos.tar.gz=86a9034fa275c0fc73d639fe6437fc4d2621bf12897c9f83a81ab6056173a95f
-dist/2025-02-18/rustc-nightly-x86_64-unknown-illumos.tar.xz=4aeef66ad8a908589ddf0d89581a6ca809b7c2a57f06bbda6fd3927b531fe07b
-dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=907aa282fb9f3d96c9fb03dadd62f4ea766e1242fe19106ae331a4f49a9b20f0
-dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=e63d13a6acd596ebfd7bf65b292eedd2a5e260b536ca11517a3fe1d8e6a6241f
-dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=b7bee098c32b321551f68e96e002f85e3a0323c864aa7f65641a58ae24f4238e
-dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=e5c22c2fab89c7ba548b11104c54e8f82cafb1979ba73a318682bb10ed9e4fb9
-dist/2025-02-18/rustc-nightly-x86_64-unknown-netbsd.tar.gz=7bf40bffe95437244f6f8a5fde69499f42d2b716e166115530fbcdbdcd837887
-dist/2025-02-18/rustc-nightly-x86_64-unknown-netbsd.tar.xz=0adeaa382f289233ffc9229e116a340ac03a861f0fdbb5bd35aaf5d0d7370877
\ No newline at end of file
+dist/2025-04-02/rustc-beta-aarch64-apple-darwin.tar.gz=42fbc48c6f9034c1d47029491e0adc7aaa1adecf429e22ea9eb6d36225ed13e7
+dist/2025-04-02/rustc-beta-aarch64-apple-darwin.tar.xz=08f88363fd42d66d537c0a296502f94c3a3fecf59a004613c9acff33eb0b0207
+dist/2025-04-02/rustc-beta-aarch64-pc-windows-msvc.tar.gz=ea47adaa63abd18bf0c11cdb381eefb2874994527005cbccc0dcace33191f9c6
+dist/2025-04-02/rustc-beta-aarch64-pc-windows-msvc.tar.xz=cefea68c789907a45f0bd4233da2e3406287ac55d1c33f8612ec1aa006b853f0
+dist/2025-04-02/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=38fa4ce395641a988247ee58c334389eda62fc1d3c0fb45157f24578319925d8
+dist/2025-04-02/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=d8d0b459acdff2a32f8c40707bf5a17b71ce86fb5ee9ad61690cba8f8227bbfc
+dist/2025-04-02/rustc-beta-aarch64-unknown-linux-musl.tar.gz=41f01647a80a7f21b85fe660af9e7964ad34f0e909d1e58c9e28e102a796791f
+dist/2025-04-02/rustc-beta-aarch64-unknown-linux-musl.tar.xz=8436eddf40ad5bf61153f24c887fb0f0e878bcc403095719b35f3147328d6406
+dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=07ee5588005a18477a7de89321e6527ee5f10af00e9c4eeb2a8c666f79d3d606
+dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=8a95664cef49c1e45b2ae61ec464a5be976e4cecd2b502a050f95b9eb25dd4c7
+dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=b9b186ea9bee58a646ce8c4c384fc4cb528c73c1fee3ea3f5028fd4b3fddab3a
+dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9f62c2ea5b67c14ab804267d449ded07c8b551536886099b02b942ce2d641790
+dist/2025-04-02/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=f07363ad0dff8b965dc10543f27cfd923266dea6284ebbb1d1b59b77f5ae2b61
+dist/2025-04-02/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=a31afc234645a7dc5dc47f05bb5321fea12931278433df834def303cdea9f52d
+dist/2025-04-02/rustc-beta-i686-pc-windows-gnu.tar.gz=f396061e8faaf66edea34b0855e2d3760fc0fd5c75e99696b50b2d4f310e11e0
+dist/2025-04-02/rustc-beta-i686-pc-windows-gnu.tar.xz=0f95f9170c5b211db29c3baac9341ef61de83511fe0000b8aae65aaf90041ae6
+dist/2025-04-02/rustc-beta-i686-pc-windows-msvc.tar.gz=82b7d1136d1b6f3d229fc77eac19d2cbfb3a46de472345b0ec3ebc152872164f
+dist/2025-04-02/rustc-beta-i686-pc-windows-msvc.tar.xz=565bde72132e77617059da66edf9262f728336a2cc2c3c7cf4d61e0a4b5e681a
+dist/2025-04-02/rustc-beta-i686-unknown-linux-gnu.tar.gz=8a3abc2a8aee8fa30699f51a216b29b41b2242143646d0f560f89bf72a0e285c
+dist/2025-04-02/rustc-beta-i686-unknown-linux-gnu.tar.xz=7d47cf99aa5fd3b5bc2caa918b4eaba793b6d38252a72fa7be631c8db27c8525
+dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=0654cf14bd3302d001fa00fe73cb7c597206c6897978b3aeefd00e9325a8bdad
+dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=6cd5c3ccb643a912d738239c0ad7464ee755cd81f45a26a9d3aa5ceeff569ba3
+dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=e3c0c5c52b04dd060f3a70b0c936dfb5c70ac29256361a491df9c898259dd551
+dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=83a9bc8f9a61b2a7fedddbdfb253aa078bc9896f179ec9b1d1bd918e7de34663
+dist/2025-04-02/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=21efa7a67647df8aa99e40317c798895321d09c48b8453e51eef1635c20e9c47
+dist/2025-04-02/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=56203ed9d3bbbab33e2825db7c72cfbe4f857f68dc98072cc98280cc4f1110d6
+dist/2025-04-02/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=76c343aa3f5c74e1419e3f2f79dd3a2091fad8f6db644cf14f7aef036c8369d0
+dist/2025-04-02/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=e9c7b97a407127e51fa49ca94c5f22c59f2f325848d55e6160d6dcf7ff690f91
+dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=27935ff4136141519b4e7b37b55253960b7fa16f5cd751d731ed85019432247b
+dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=fd37c12a55055bc4a2f0e002b3126e6396df8d49254b2a8a7a45354aac46bb2c
+dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=cbeba9993d03c6c0c2c508414bee04665abb9c084c736b39c5b8d38c8f63402d
+dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=e92f69d85929c81e3c91b2ab45eec418afc65edf6f8bf9383148a98b052353df
+dist/2025-04-02/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=31a8ae1e64fb86a499518d7711595d653db56527aaedea06bc2bbcb912568844
+dist/2025-04-02/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=7d001ad6c4825d5323813ed19747cc3e3d2dcbbe76317329a52127b3de37ee88
+dist/2025-04-02/rustc-beta-s390x-unknown-linux-gnu.tar.gz=c69d15e75d51caa0cf77fbe149d43b62c327896bdeb0c6c73fa7240404289862
+dist/2025-04-02/rustc-beta-s390x-unknown-linux-gnu.tar.xz=cf80772ba9eed4885a28aab38323f0ed24ab220339a3b8a148b7c27860c48c19
+dist/2025-04-02/rustc-beta-x86_64-apple-darwin.tar.gz=be22d207f8fd4722d69f6fdc56c57618ec01c54c5b6f3a8506c62583259d433a
+dist/2025-04-02/rustc-beta-x86_64-apple-darwin.tar.xz=04feea9824748ae01b4f4f85d15adc5baee23c996c22de86041888466ae69512
+dist/2025-04-02/rustc-beta-x86_64-pc-windows-gnu.tar.gz=8c75005f0309d30e7c272adce173adb253874ce881b347946b6ffe5a07067439
+dist/2025-04-02/rustc-beta-x86_64-pc-windows-gnu.tar.xz=7b87c4ab5291d9ad3670f4e9ee98fe9f6f877ab8d4952109d7e5e9d20181a700
+dist/2025-04-02/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a96d89ba655db5317dd51ffa2ebb81b7bdb76b19cf12de36e9d0aba2c5877ae2
+dist/2025-04-02/rustc-beta-x86_64-pc-windows-msvc.tar.xz=84bcfd763eba610c78223697393ea97f1f70e567a44b8cfe22db79f1cade4201
+dist/2025-04-02/rustc-beta-x86_64-unknown-freebsd.tar.gz=95ff7349cf12e49028256c06c8517719cada2720d4db80bfe7531289bbcdbde9
+dist/2025-04-02/rustc-beta-x86_64-unknown-freebsd.tar.xz=c8d0147c625faa5ce0e75c2509827bc4b190ad286e41411bce92023e00eb7a1d
+dist/2025-04-02/rustc-beta-x86_64-unknown-illumos.tar.gz=4be80235a110028d64404e532eb20af37e46db72a7ac3a0cf7c94ddf463c461f
+dist/2025-04-02/rustc-beta-x86_64-unknown-illumos.tar.xz=b18ea9a5c262c2f7505305110473cc15bd2c4ed9d583f07c15635406c050be08
+dist/2025-04-02/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=234027a0075224ea157efaf39173ece43f9ca7d69d86e4790a2a038f7e6d98a6
+dist/2025-04-02/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=308a8ee2855a6471db3b3b64cb06e355e31d0d617ebc9f30757bb7db5f6fc7c0
+dist/2025-04-02/rustc-beta-x86_64-unknown-linux-musl.tar.gz=10f39cc94f39bcf17d0fa3b8efeb4db72408fba694e5eb0f175e7465f6d2de49
+dist/2025-04-02/rustc-beta-x86_64-unknown-linux-musl.tar.xz=6b0d16b46347fdbcddfafad8209df19515059eddce1e048ecf1585341fa1e586
+dist/2025-04-02/rustc-beta-x86_64-unknown-netbsd.tar.gz=09f482425c92396f7e4ae3baf625dbcad1d886d82ecfb605b50393abdc23ce15
+dist/2025-04-02/rustc-beta-x86_64-unknown-netbsd.tar.xz=bac2f1a493bc2c5fa6cab1f58ff536cbeba55f77141b34636bfded9e3ff167b5
+dist/2025-04-02/rust-std-beta-aarch64-apple-darwin.tar.gz=8875ade1dd8ba0bca0c12860a076df1f089195a52adc546679025c405bef4dd1
+dist/2025-04-02/rust-std-beta-aarch64-apple-darwin.tar.xz=0a0593ab4c95802b0ed810c0442e13ad9304712c2f7c30a30c734523a7448d8a
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios.tar.gz=839086e20098c305adcdf9103cdf3f29a14c4140b4c1b728723e7aedad966883
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios.tar.xz=70f1832193e77a2018088943b531bdbacbe5404d5d7a34393e03f40329e742ce
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=94adeb2e63a91c09001facbc554678227a3717748104424e4fea71db3d5a16be
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=73c9bb75eb6fa4cf613c7a2b0e237472e144a1469cb043194ad7802052149fee
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios-sim.tar.gz=0e01ed2620887b893687758d62422f661429e3c4566ff52d967463eca89f54c5
+dist/2025-04-02/rust-std-beta-aarch64-apple-ios-sim.tar.xz=c26beb8ea9f11845ce79d4f0ec2616ce82dfbc4fefadfc7f94a1df17f4d5bec2
+dist/2025-04-02/rust-std-beta-aarch64-linux-android.tar.gz=64047673efa9d9bad660e2a44f82e6f929c881fe205523bff10a549505d12b72
+dist/2025-04-02/rust-std-beta-aarch64-linux-android.tar.xz=0e4c6b76e8d92023533aef6fe377c9bd45ef9c1da517eda7bfefec85b966780b
+dist/2025-04-02/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=a25c50a86e5d674600cec5bd9e7939bf36b0afa766445b0d71673431388d285c
+dist/2025-04-02/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=8060a4c5337fa6c34b3f08ddb8886beeb5bafd2b02544b08a7cfcb466a27a972
+dist/2025-04-02/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=efd76703934ae0187308eec9b3439abea0dd4437ac353d5dc07d92f9440ab9ee
+dist/2025-04-02/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=007462f554b0c6d2b165d727bf72b1ad4347a53869d672fcbf48db2c1dcf128d
+dist/2025-04-02/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=e0dc54be7890edef123d2dc31f0dcddd1c807cc060a34f475093cab79100d9fd
+dist/2025-04-02/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=01c06c1d61c512a034a109f50f957e4496639549837b63464acb4fb24ff65e09
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=2042d37b09618379dd91125d20803e2d97d5f3f3794e01ed27597a0f3b27c102
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=568f0b8da190daf78cd8573b0408db2ecc2c07b1cb1fa463239581963738e9de
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=386b1e4786dbfe342626cde4c3708abd04d9862d69717c7acd5dfe82427e38f9
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=781d0f9417e1b3d33d95e3c5b82ba7e481a610dc468345119e09a52b1d170045
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=8673d059524ac141a8907decfda36c8afac81fd36dd75f78df750a6d52ada221
+dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=8e8afe45e9bb84ebc3e02f0b4b71dbcec7c844128329d31067303b86113c3439
+dist/2025-04-02/rust-std-beta-aarch64-unknown-none.tar.gz=72e1dce3c1f821b6018ec155bff250b941afcfcf1697b440a69822b10e929b94
+dist/2025-04-02/rust-std-beta-aarch64-unknown-none.tar.xz=7030883ad3ca170a061972707c488fc25d4dc8ab0f60a1b9b54240e42ca713ba
+dist/2025-04-02/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=28f87a505ca4e2c33015338d73cfdf5c2fdb1f5775f82ec432d033a36880351d
+dist/2025-04-02/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=45669a09671c183d702a31b6ecf095e8f422797c4e242063c7864180c6f657a4
+dist/2025-04-02/rust-std-beta-aarch64-unknown-uefi.tar.gz=1ad54cabda8bfabfd93e16c564c0950c26e1502662d5f4ce3b33b4ee265b9a2d
+dist/2025-04-02/rust-std-beta-aarch64-unknown-uefi.tar.xz=a79f9d7eb4297994b2e87d48106a959c82bc4387433e5e86dc8caddde29a8a4e
+dist/2025-04-02/rust-std-beta-arm-linux-androideabi.tar.gz=75192092fa7a40051a70a843cf75513de2c50d66927f16b122f7417c1d4f25e7
+dist/2025-04-02/rust-std-beta-arm-linux-androideabi.tar.xz=843dde45dfa49b5cc97266c61d8e58dfb22dbf2288e6e8baaef769eaf59675cc
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=03ccaa5e246502fc61fea1e0b33f5c60b5895cd0b5b932bf640d62e97164b457
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=a73525dcab3a0f3bc7064c8a6cdeb9b0e5b359501cb7e8fe20075a0e97b2a5ba
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=8c851fc122d14beee962e15fdb95c2873769805180be30723f418d84cbc0a8b8
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=8524ad1b7723a4a5898837d5b526fb11ffcd039b2c4835a2e139071f6cfd4e9f
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=b108ec4460d4f6ca79813e6d2d4cb7061fa522a990333fb9f4f927b0fc659624
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0bdb617dfa833c62c03f5bfd2f06ed3ca1479908d860f888d661794188bd57d6
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=19f9fff71344f7a42f958c3efec720e4b2e0d67ba36a5fd66946e74811259f2b
+dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=0cdfe9b4a8bc4b63637cfd9766c3e0e1d3dcd6d2e82fe35f57973a0081e630ec
+dist/2025-04-02/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=a8490374598bbfa42931bbfba51ecc0186c476217eb79408ae6b80a4ba6de9f2
+dist/2025-04-02/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=2bc2838320667f060c140345d1c26aedf90bf5efb1f72e6722b74d32f876901c
+dist/2025-04-02/rust-std-beta-armebv7r-none-eabi.tar.gz=9a237e1dbd2e3b555aa3932351d1c20a0f9f2f06e810abd254b5ca152aace687
+dist/2025-04-02/rust-std-beta-armebv7r-none-eabi.tar.xz=f4978bf9af719f0b6e8300ea862fe617e983e5443a46c769d60d5e8c4d556ba8
+dist/2025-04-02/rust-std-beta-armebv7r-none-eabihf.tar.gz=c1476718625d5d5d42b60faa9ade845272b0b71e91d77a9cdd271c4682c900d2
+dist/2025-04-02/rust-std-beta-armebv7r-none-eabihf.tar.xz=f8ab07e99983fc7395841cc9ed7ce7cfaedd87bfb91214bd83508ad96aef0c0b
+dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=649071a7de4792ff75da59ca421ea1cb364c011db97e73c480982a5f9f06b8aa
+dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=529aac0b0a385fa5ddb76a88eb6923bcc981679caab2d1c374d443383c99f52a
+dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=8bdf3412b0b557485099db86afcdf58293bfd4c09c4b360c2d9733788b612122
+dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=5d5a4ebed984a0930b214ec0b11e20fd9a7b8d5dc2d00985b75a77c8febcf441
+dist/2025-04-02/rust-std-beta-armv7-linux-androideabi.tar.gz=2c03cbb393641876bebad9b76465ac7f96adb82c14dcc9b5bc01a82e5110b892
+dist/2025-04-02/rust-std-beta-armv7-linux-androideabi.tar.xz=67d86fa728178c30cd7a33e0c488c32f58ae0caeb9a982370e080ea38853830b
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=3737dd5f80f35f3fecf5cd8324c9226f45bb0bfd040998d91509a2c6fd8967f1
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=8f9f710c92af058d5a07c93b4cfd45b7d30e63ab79bea7f79530537aae2dd836
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=6ecb3e238e125e88851dba9711b2b32f4de1da55de36a62373bfcc42d001fa0b
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=7d6807d24afe4825b77c1cb74c1412b814cf2508f5b40debb55b3f264e02eb6a
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=a15fccced78065f748a5c4f66763b8940ae3e52b5048b5ee1fab6b0b7b40c701
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=20bc43c1b5742a9c7a97ade055441ca1ca153dab9602db3ffaf1ac518713568e
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=b01929a0f18b1a41b65307a04d1273d2197df83b3c124f80659ef8fa4f8c4577
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=2a13350da7c632d3878ca8da8a7d0bda60c850df8e5d824956082b524eb136fe
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=11bc9fd437be07cb454182b0d7b287ec030f7d8904f096b73beda6480ba33285
+dist/2025-04-02/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=31e06feb45173fec8e58cf92216e44d556587fe2ed866102206e23514c73d3f0
+dist/2025-04-02/rust-std-beta-armv7a-none-eabi.tar.gz=aebbae792c070adea3f10135c02b2cf5d623b84e765ec3a72c89275f53a85384
+dist/2025-04-02/rust-std-beta-armv7a-none-eabi.tar.xz=e80dcb152e7a8337fbbff6a5c8dfcd9c6da4b753da6b14e63fe7c15cc0836359
+dist/2025-04-02/rust-std-beta-armv7r-none-eabi.tar.gz=e79846c1203d5d375c7c1cff1c843cb6fcd4e33bbc71b2363e12fc900bbd72bd
+dist/2025-04-02/rust-std-beta-armv7r-none-eabi.tar.xz=0e24e48461cc46edef0237e38480ac806d0521c73ea366668e731f29b638d7c9
+dist/2025-04-02/rust-std-beta-armv7r-none-eabihf.tar.gz=fd2a9b48ea203b44567cfdcfcfb21d5d803896fdfdc5f3aa191e3fa7472b98db
+dist/2025-04-02/rust-std-beta-armv7r-none-eabihf.tar.xz=2b85d461bed34a97cf832a7c0e1d4179d7800ef47523a8e31d635b8de5dd44a7
+dist/2025-04-02/rust-std-beta-i586-unknown-linux-gnu.tar.gz=cab412c30b27060cdcb29adb947dc070875813726707dff121c4a1aa8615646d
+dist/2025-04-02/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1b8d469fbb8903a5f4f5eb6ccee7bdf28cc56137b6b212fdfa1aed647f4c347b
+dist/2025-04-02/rust-std-beta-i586-unknown-linux-musl.tar.gz=93fa0383e32f18567c3c156f3cddde1fa4296003f98cdd22b0b5628d69d5208a
+dist/2025-04-02/rust-std-beta-i586-unknown-linux-musl.tar.xz=71ae00b01ffbfdc6654d0fd14df204adb7d499ac71e59c93affff91d58833d88
+dist/2025-04-02/rust-std-beta-i686-linux-android.tar.gz=4c6f4764e284ff29958417295ddc5d3316072fc9eac87dfed8b694c237aa4f88
+dist/2025-04-02/rust-std-beta-i686-linux-android.tar.xz=f471a7abb2d447f668f01973be4712e20c6dd29b210a96517b277e62c6d7de07
+dist/2025-04-02/rust-std-beta-i686-pc-windows-gnu.tar.gz=0c5efb9792502fc08174b2556f5c91f3edbad6e02de5e230f39c5fa011fc935c
+dist/2025-04-02/rust-std-beta-i686-pc-windows-gnu.tar.xz=b6a87360e7be832288e59239d41e809db01710ccae5ef37bcbe7b0eb1d311e66
+dist/2025-04-02/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=0429745cd95a198a7a42a1ce0c7ab2d502f3ff3eee81104fe6d5d4d5dab9447e
+dist/2025-04-02/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=bcb43c9e2d4a49c18d39e041d28021f2302707ae9ac20ef37f4d467fd2cd3975
+dist/2025-04-02/rust-std-beta-i686-pc-windows-msvc.tar.gz=e1d8c40e61701c6bfd519125169cc1ab1d60e9a58238351bbeda0ccc5522cc49
+dist/2025-04-02/rust-std-beta-i686-pc-windows-msvc.tar.xz=1f87f343a90f6e88cb3173d52f4f88d8abdb0c1a613681c92675c1acc340aa54
+dist/2025-04-02/rust-std-beta-i686-unknown-freebsd.tar.gz=5862f33548bef1aa21b3d63caefa12ee34775cb378f89c4dc161e081a773d11e
+dist/2025-04-02/rust-std-beta-i686-unknown-freebsd.tar.xz=ed3460948031d0c4e97f7b1b77062f388d133db2b2212518eabd3198e72c031c
+dist/2025-04-02/rust-std-beta-i686-unknown-linux-gnu.tar.gz=3a6edd9f412a274e372c9555b6758d540d06ac08efd21ce95df1ed4d30418afd
+dist/2025-04-02/rust-std-beta-i686-unknown-linux-gnu.tar.xz=8338baaa50b9cb08a28f7bb21a22deef849f8809282c661e48c486a168b6249e
+dist/2025-04-02/rust-std-beta-i686-unknown-linux-musl.tar.gz=56ab80fc6cb75a0d66c477e76f87918645bc3b616cf704306820832681022768
+dist/2025-04-02/rust-std-beta-i686-unknown-linux-musl.tar.xz=94efb810dbee977ecb3ff5a42a5a620d720c237da58d974ba1f376c99947baf5
+dist/2025-04-02/rust-std-beta-i686-unknown-uefi.tar.gz=64cb107065bde9b30c78b9b342211c4e6cd2c3ed726155dacfcf5958ba869a82
+dist/2025-04-02/rust-std-beta-i686-unknown-uefi.tar.xz=ff1bc215b4aba25f59eeee8285967e24b78f6965473ea8bb30186ab55804f88a
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=da1d33b266e1dd277f97f63228843765706f26c9f75c4b5171f49c2762fed870
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=8309c9c4a03df90eb53116b5c5c4870d103911227848919580a48e5e85954709
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=26a3115d5354f878f80bef1c83a44af185e2780882e17143ca57aff078d123a0
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=12431c3b50276f352a3ea71c74db279cd03c2edfb3edf743f81774d4274f7ef9
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-none.tar.gz=ac67b23f84d09ab17d26f30deb38a128ccf812a561738327effe48ecd0caa319
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-none.tar.xz=5508b02465d3dbb40512a142eabb27817807d2af153089f7d05a0af355fdb245
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=a79a59139e13166cb1121d703cee113bf92821f937d433cb9a2c00567280a4e2
+dist/2025-04-02/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=8c3b5501050f57125cc89e6525b780ca0e18d2d5318f779894ab97efef761fb3
+dist/2025-04-02/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=84a48148eb313f236f85a4907af615b7af4c3ce3d9065ffe0db54458852690ab
+dist/2025-04-02/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=26281622332b438bc43b8f46921153a45c6236a4c0939c76fdb4d9fb3d29cbbb
+dist/2025-04-02/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=0eef233c871404b913c6458d8005d362e3c24fcb0670ac49a7e67b1a503b4b29
+dist/2025-04-02/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=b96422b0f33446abee203160a22e9bac8861e1c7988b2cef463276743001fc7c
+dist/2025-04-02/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=18db97406a6e644734c7890991cb3006fabe1e1a185f89d108d28a992ed7c17c
+dist/2025-04-02/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=eea42655b5335643905acaa3d8ff1774e2c1a39ffde363c2073a8636c153087a
+dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=5feaf6f3859204979fb4dab03fc93428abd103d61822d6e4e9a2f5d6d155213a
+dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=98f8e695253c9dad3d82638bd69c084a3e7a96d17eb1dba0f90a42df993de864
+dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=e028f2ec967ecee5d9e7b48058209428ed220c5da2c00f2753f8d4e98951e168
+dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=69f508ffcb55347dbb773cfa22a1f7a6362f3aff6a48296b50945422ea82c7b5
+dist/2025-04-02/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=ea30bf48fcb3873db4019ae3d248e1db868e1f7fc49e4549737aae58b3b49b22
+dist/2025-04-02/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=c3724aaa58f812dc8283622f27e215546d8522b6ecdf1d191010dde3a1ba3344
+dist/2025-04-02/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=9d24eb785b66796309c2f03944719fb6b6980ae8fb7ca97084fcfdea0094bcce
+dist/2025-04-02/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=f6b2233474eb64d041e6bd8f1b6dee3eaf775b6b5a7ddec703689352cf88f6a2
+dist/2025-04-02/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=8a5c94055180b9a1226a23c5992a622062ac52cddf91651a91a5d236be46d0c8
+dist/2025-04-02/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=7ea826d6c58fe1ef1c9374aef0cbfec5495daddcda581b231d18397330d9e248
+dist/2025-04-02/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=811881bd5b514c89c316453ea1214fbeccf5388f18468cc83676a879d58f53ab
+dist/2025-04-02/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=9448b7bad586237faa4f090ce8c3de83b62d19fbe37104ae32032d9df709d2e6
+dist/2025-04-02/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=dd9252a03b0a888ee7598a84c20aac721739c2caf9c5b585274d2a30d7fcbcb6
+dist/2025-04-02/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d1f134647fe0c3efcce80351cf9e4786ca8e3e336c0316b7c28ff07b78907c73
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=4f688c40457ba71542438fbc100b62b5f081435567f965512481ccf3d002826d
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=a474fddf29c6979e0870c397c19f64de00650893a781eb51d9e136802bfabbfd
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=7071209fdf0d2605b623ef96c934ed039d1dd95a68c438a8c563530ed48fb4e2
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=1328504e895dc9bbc36ac697bd5031e0034b2468fc66a91e42b39a4d35d4ea8b
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=e7878c1137279790205e62f9c363a6f45e2a8cd9c30702a53478a8104dc87a6b
+dist/2025-04-02/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=f373b1d79547c385a01c2b36951eb3750a4cf3bcaaa213587af9a6b4274dc924
+dist/2025-04-02/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=4832338ebc25d088e30952605b3f6491d96003790df5b10c5c56e29ec69ac646
+dist/2025-04-02/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=d782dac690b3da2b96206809512f1ae82fb4a73ee387d91128ae0d98bf51ef3a
+dist/2025-04-02/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=faccf22845e31101a420796d9065b350092cbee29d755c2369ee36cc7172866f
+dist/2025-04-02/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=f296c5726380b1f2b8603a079e8dfdfa7e4a97a499b1e86874753c312768ab15
+dist/2025-04-02/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=b8a8fd8fda8b99d96d6f890bcd0c9073393441e85a4cda169b6fc7dbb7296984
+dist/2025-04-02/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=923a0530224f0631162f7b86bef79be85f45071f62ca4f5de0588fb5ca6affa8
+dist/2025-04-02/rust-std-beta-sparcv9-sun-solaris.tar.gz=944a83365d3c46313e28b1d3a5b0e52e57ce88b3eaaf0f7f53234d4423ce9ca7
+dist/2025-04-02/rust-std-beta-sparcv9-sun-solaris.tar.xz=be0c983c443f05feb4614d97336755894b3ffc5083d852bd84ee7cd9e5edfa03
+dist/2025-04-02/rust-std-beta-thumbv6m-none-eabi.tar.gz=08905a766352dd259be919aeb366e965dbbd4066c398dc4d26efa333b0ac46b8
+dist/2025-04-02/rust-std-beta-thumbv6m-none-eabi.tar.xz=4fa005107c3d1addb242179c03a804a27d34ca68bd76c092a41a197da56abce1
+dist/2025-04-02/rust-std-beta-thumbv7em-none-eabi.tar.gz=e6ccc1004004ed759b1814daae0b50a3a0adca9786688ef9cc601a0a19edc72a
+dist/2025-04-02/rust-std-beta-thumbv7em-none-eabi.tar.xz=fc23abf9c086a34264bfcfe7c4876ec65ce54f8ca73a98020bb8eab6d2c51d57
+dist/2025-04-02/rust-std-beta-thumbv7em-none-eabihf.tar.gz=e8121551c0529f73796bc157bf916e3608685454a02a81d170a258a7465b5b7c
+dist/2025-04-02/rust-std-beta-thumbv7em-none-eabihf.tar.xz=2695f76447ff5d70aa3cc6b6690267b31b9aa4ddc7c45205e529f92d234483a0
+dist/2025-04-02/rust-std-beta-thumbv7m-none-eabi.tar.gz=36d7fb4edd572c7d73501aab7c89737ee0036d606700c728f430142e91649eb0
+dist/2025-04-02/rust-std-beta-thumbv7m-none-eabi.tar.xz=a6e59eaed0ab3e310852d9a75fc43600c7c2eee0c808224b87bcb8c18df4ada6
+dist/2025-04-02/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=6bc70be43929b77f3508b1872e5b09227aebce1c7c9c943995b5df92cf6d9181
+dist/2025-04-02/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=37b956924534aed1ae7ef9908d38bf724c6903591269136d23e293e17a0d333f
+dist/2025-04-02/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=041562edada0caeea67fe7f3ffb5b9f8c1b506c0d5ee7b657c5ee2afbefba7fa
+dist/2025-04-02/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=8980372a7e9a072b1e0b954569e59df260583a3371daf005c5a83576688562d1
+dist/2025-04-02/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=83f461ac0ebcc05d5cbf67a6585b49dc7b245c8788dc3a75e08a93be41e2615f
+dist/2025-04-02/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=6ac8847ce601c8dfeffff07915de06a605b3c685f81b90f87b092897c2afb973
+dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=bfcd9ff7dc9bb5e95bd563d750240efcbc3bfa1a21a9f9a2786ef37f665b7e43
+dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=4507383395a26d41abd71041b162dfc5e9471a4c624d9fd6ad310e184ef15d01
+dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=b4d1940ea5e24cd6a0ba3906c98d2b03e4a18927619152b43e91832733316258
+dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=45eec7770344beb84cf418cf7818216d123136465785f4742127f6f5a8c5ce27
+dist/2025-04-02/rust-std-beta-wasm32-unknown-emscripten.tar.gz=19bf2f4bf64f874ccfd84b820b7200e83e896c96a396edd7bd10301d2bc89d98
+dist/2025-04-02/rust-std-beta-wasm32-unknown-emscripten.tar.xz=4c616b7bd972c09461f0bccf5009bc574dcfa8bdce2dd97d17fcffd64542e496
+dist/2025-04-02/rust-std-beta-wasm32-unknown-unknown.tar.gz=69bcb61fd0f8bd7d2da225a4525a877cce003afd7fc3d789c385f164959cd41a
+dist/2025-04-02/rust-std-beta-wasm32-unknown-unknown.tar.xz=0372a64eda0c7249ce5fbcbbbf29e145e969b383a73b7c470f0b583720fcdbe2
+dist/2025-04-02/rust-std-beta-wasm32-wasip1.tar.gz=f76a2a3f4702eb781a680ebd4346afb4c26ca2235e62bad144b057860c09b8a8
+dist/2025-04-02/rust-std-beta-wasm32-wasip1.tar.xz=173bc3317b59a01036a9c8e0bccc570fd6f5174d15f94634f53d81dec3d2cd68
+dist/2025-04-02/rust-std-beta-wasm32-wasip1-threads.tar.gz=18e05380478ed0b3f76d9062fade2be2e66c039dcc470ffb01be3c8dffc79995
+dist/2025-04-02/rust-std-beta-wasm32-wasip1-threads.tar.xz=3d477eb85308f73d1081d6dd3e54577be4bd84f291a50af0e3be15fa8aa36db6
+dist/2025-04-02/rust-std-beta-wasm32-wasip2.tar.gz=3444883960a9f8b831d1f26ee17ef082a2029cdc2e9b45ce5af4d6565d3a526e
+dist/2025-04-02/rust-std-beta-wasm32-wasip2.tar.xz=867361c7ba912b404c426807a60625a1f830707a172f7da139c1a892aa85bf35
+dist/2025-04-02/rust-std-beta-wasm32v1-none.tar.gz=d15017a323c662a1e8c65f51e66151138c2255cd8842a67e990000606dac839f
+dist/2025-04-02/rust-std-beta-wasm32v1-none.tar.xz=f3b32484ef287317187ca0bd5245b1793ae40d50290a2882419da8503b8243f3
+dist/2025-04-02/rust-std-beta-x86_64-apple-darwin.tar.gz=179be6a29fcf16b4c18775208569a051f2f5a38558e751d2dda0a42027868843
+dist/2025-04-02/rust-std-beta-x86_64-apple-darwin.tar.xz=912f7f8d7117a5cac85dffee5ffd9f2c1cf237477bb0f9e1127afff1f0cd4757
+dist/2025-04-02/rust-std-beta-x86_64-apple-ios.tar.gz=9d2f3230bd82ba9d45e572b45ec63c63cfb592dba6311b6a16de075f18c86999
+dist/2025-04-02/rust-std-beta-x86_64-apple-ios.tar.xz=c8ff77db2d081444ab5167764465beb33046cc81cf2e8dbbd8e9a7328306762c
+dist/2025-04-02/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=76c9b2ae710fed611a2294a5e4bb6597b07d78f0bbd3a5a0d15c3320f38a0017
+dist/2025-04-02/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=b9c485a3824c971a42c10af26cf06c539c34fa429e92601a1978280867029e62
+dist/2025-04-02/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=a223c08b88c768d97bf9f071c74d9548acf00bbb097b8c8427c2ec87ca205597
+dist/2025-04-02/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=34ddb3db8a71edabb4d0fd8d52a164dbca5a5cd96d6ba131e7d439c333726f78
+dist/2025-04-02/rust-std-beta-x86_64-linux-android.tar.gz=9ba28bf95c75ca0d69461d1c044902443053b64678b540967a97c7cd2eb7cc4c
+dist/2025-04-02/rust-std-beta-x86_64-linux-android.tar.xz=09e35188a801371a55abeb9e2ee455ebd26d41b8eb561b8016ecacfc7ba20c90
+dist/2025-04-02/rust-std-beta-x86_64-pc-solaris.tar.gz=c1f2fb4b90cf258dfa1a52167ba925b583dc889ec1c3c48958560ff3b7b79b13
+dist/2025-04-02/rust-std-beta-x86_64-pc-solaris.tar.xz=d71f2bade21f751d9592e865ce3722b5d3b9abc49e55ca9d04c02d658360b6ad
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=691c23504582e6db1cf883f52b5378aad3c42da7e2d2237e54601be9c8d16cac
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=22e7327c5ba22863cb62cc5331862b8c2b4b10a732637729b5e1504034aa2cf1
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=81b7dda817a7dbc8b33542c356e0c5e5605b7c60a2fee13f4a266c8d970a3f54
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=09e4c9804f7489b337ccf66426e18e7522dcba24234b289a39eb63c8242353d0
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=a8188567321462309fb63af38f652c6a7448ebaae1425b9ec20d2fe2a12e8896
+dist/2025-04-02/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=5284f85dce61b2b021888b6b82995aa7b4a14a979b42b83499a810c261fc183e
+dist/2025-04-02/rust-std-beta-x86_64-unknown-freebsd.tar.gz=eb57c8ca7f515386d60a88e56443e377aae70e185ac52a62869e115c636a2bcc
+dist/2025-04-02/rust-std-beta-x86_64-unknown-freebsd.tar.xz=8bef59b74196fa9f7839bb491f6b32d0761a45c8d7178980ee3afd80231b836e
+dist/2025-04-02/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=f43f402881f4558e3df4a7ace68ba80caa9354cfa5a8b1efac89f95e38386253
+dist/2025-04-02/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=ea7d09c015c057591ff51b808cca9c8c1d973de3a9033fe42c1bf34d748d03a6
+dist/2025-04-02/rust-std-beta-x86_64-unknown-illumos.tar.gz=a4835455348bc5b154b1bba63aa03d2294713589214b50d3babae3e0f9918a3c
+dist/2025-04-02/rust-std-beta-x86_64-unknown-illumos.tar.xz=711920e7491332251fb672abdc7685fa940f863d8e182e2ae9d9347d7fa6a725
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=1b8324839c0e10e410f29bd471f6c49eb4710adbe172d6bef3e619ae95d47d02
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=223b41f16a80b9c404f5af9a194b7414ef354681f911839353f24b44eed91494
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=6d8d8d9fd6336de0ebcb58fa85aa0d11e62a60d6c6ca01d71da0bdf668d216c1
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=033df93011b4461cde64c4230c495bad1523b9b38f5b0de56dd928c1da85b577
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=70a441c0cf8ca25abc1f722c1db5dde8b5fd3b90c767895b7518fc58c2678390
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=b5584d6d0031f8230a40f5ed76570ab1396c8997c3e957ca159d72a5dc201a2d
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=2596cdc3708d82aa93a8a1f595238fe9fd7b5b05a4886e7e390ca3b86d352e7e
+dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=c03901c0c8434b5db244c22145870e7d933b9060af3b23f24a765c755098a3a1
+dist/2025-04-02/rust-std-beta-x86_64-unknown-netbsd.tar.gz=82bc22594dc602b27edf8233bd9c4fbf0323999ce99ff2a7ddd0ce9268647eb1
+dist/2025-04-02/rust-std-beta-x86_64-unknown-netbsd.tar.xz=86f674f5e19a1b1780f06a6d5add06fd4240430233b7c3f5203a4daa5f444673
+dist/2025-04-02/rust-std-beta-x86_64-unknown-none.tar.gz=ca7882354f4274dc405034aa6edbda685b9d76bc6e5905074d2aaf8c35b35a95
+dist/2025-04-02/rust-std-beta-x86_64-unknown-none.tar.xz=ed6c828fdafcf87a68f522379f11c44eff1a4be1bf027d9888d1f17f22e9ca61
+dist/2025-04-02/rust-std-beta-x86_64-unknown-redox.tar.gz=6f8ab182274e2f5b0fa82fdc5c6e3776ba969e6ee6f6098ce6d170f6685f55c2
+dist/2025-04-02/rust-std-beta-x86_64-unknown-redox.tar.xz=ee061d725f657a2e52114f282be0cab1a6e542a0270b11782c36e8737ed84f32
+dist/2025-04-02/rust-std-beta-x86_64-unknown-uefi.tar.gz=0324f537f463738bbdbf40b92423df6c6068f76c583872d6070d6a41c5169dac
+dist/2025-04-02/rust-std-beta-x86_64-unknown-uefi.tar.xz=2cd2727f71b14c06eb0a14fa532e5b3bc66f8b983c021f3201c327606b04511e
+dist/2025-04-02/cargo-beta-aarch64-apple-darwin.tar.gz=76010b5a9f8dff0102a18de75e818c51b915a3bcff428fc48973728577c2ecd3
+dist/2025-04-02/cargo-beta-aarch64-apple-darwin.tar.xz=f0f03ece675cfaa9dd0f00204d7ddd4086a45357f09cac9d800d37bef8d0db33
+dist/2025-04-02/cargo-beta-aarch64-pc-windows-msvc.tar.gz=bf4ab12afcea7911ab973177de83b7bbdfd0000e3090331f31a595d57819ed6d
+dist/2025-04-02/cargo-beta-aarch64-pc-windows-msvc.tar.xz=156fc94166e5f2af91fd9a36c67b545c0eff63dad51fcd81571cce01447c1c1b
+dist/2025-04-02/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=c86bbf8091188ab9f7d41e566ef628a657d66683884333c3851e99edaea6e279
+dist/2025-04-02/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=610383a4efb93ab53cc747ba038888742346499407c982b7bc8c0c41689cf453
+dist/2025-04-02/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7d427779360c9cba5903c2a0183be1c1759cb2c2f2b77bd2f64b409821fabb64
+dist/2025-04-02/cargo-beta-aarch64-unknown-linux-musl.tar.xz=29bda8bd7dcee65315b8c14a527f4e4b4dd678b35dd430591f7c71712ecbd2f9
+dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=ef6d6a810eecb3a38940634b653257070dcfcff52c2d8321fa3a933d41c7ed73
+dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=79796d83949811776aaedc7e6db6d32374c07b8f8d256d9b871de335bf5e7074
+dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=fa93a1285a97453e2aaaf9cf392abb4ff9a419451e925959470166522e54b1dc
+dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=acb69df00475904faccf18729030a70e8ce21543189d48c7102330a98a12edf1
+dist/2025-04-02/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=7141bf32c173d26f34571b2dfb890187d866f113e28b63908841377e48dbc6ab
+dist/2025-04-02/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=249f3c535805fb2510d13338401e9ae96f16e6996e58551025b35676a1147ab5
+dist/2025-04-02/cargo-beta-i686-pc-windows-gnu.tar.gz=fe4f5f35ecac25bc3726ffecbe3e650d51adb9ea13dc5153a0699ea8d8776d13
+dist/2025-04-02/cargo-beta-i686-pc-windows-gnu.tar.xz=b7b8432464eb793e9a651c4c38ee8abe76421a9be7f75e96237a4ef938f927f9
+dist/2025-04-02/cargo-beta-i686-pc-windows-msvc.tar.gz=a283da65d3a75435ff3d05441fd0337472fd16325531086e90b01cc5d5bd221a
+dist/2025-04-02/cargo-beta-i686-pc-windows-msvc.tar.xz=ae19f98c901228ae5c7573cebde4816517bdb8d03dbdc7b92d95518d27d93531
+dist/2025-04-02/cargo-beta-i686-unknown-linux-gnu.tar.gz=e3c5b2560f64c8056ef82ed0cd659d35fda5181f19fa670b962228142398efbc
+dist/2025-04-02/cargo-beta-i686-unknown-linux-gnu.tar.xz=3fc435b8a186f6ec1b7ebc38c92c2e23e1bd786415fc33e7743ef95c37c69b45
+dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=bcab46663be61e979b7a89792d164e182d5482ad9b444a969dbb304c5dad8c8c
+dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=9e2ecb90d85a4aca95211892a6a41fde09ce1e4f44a60caab9aeb61833191d36
+dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=3c5c40f61e85663d03fe51f63d505d8dca73f94bfb3eed29f6e1396b31e0a554
+dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=775c56ce638e0923758ab5f82a87c15b7a1500d10e0be2433af40364a0455d58
+dist/2025-04-02/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=c1a144dc83b673e0375e8f718cde6672ca276dbab9161d7f3e002c6273352c1b
+dist/2025-04-02/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1b41b3396340c97c122661c95fe54265036e721f1750bad3a8fe4920f6f52b34
+dist/2025-04-02/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2a43a7682ea3da8b911b09a7bb4a3a75fc3facb64fc952e51ff35c63e6630b75
+dist/2025-04-02/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=73a3383196527e63716de1b1cab233226519873556a755a7e47279f799936116
+dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d5f521839bd4b258454097cf97b056508e6f9103f7312c93b632ae44ac9f7dc0
+dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=c4fc5ff91bc1054e8497efa53ee6a9a9eb7f06927cd314a681e16b6d46b08440
+dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=5b0d569fe4ec84d6e7526af9d9794b440e8f1b5fc1b09e951678b09fd3ff97fb
+dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=e9c68eee5763c624cbe312bc1b50b6c3172eb7997e209371692e7f897d13b03b
+dist/2025-04-02/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=96962461e7f6744a46f18a557a4701d35d6fa3b6d960d854f4c3effe6f2636f8
+dist/2025-04-02/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=4d6029204f930543afeeaf44d9e635692c86c9daaaac6301cccbe076c7facbe5
+dist/2025-04-02/cargo-beta-s390x-unknown-linux-gnu.tar.gz=f40421ea02804c3089420e5ca13838f94fb89c114de9a9e596e9a1207d2166d7
+dist/2025-04-02/cargo-beta-s390x-unknown-linux-gnu.tar.xz=77521eb215cded6886267644661b3357590f20368383f314da8f310197e9679e
+dist/2025-04-02/cargo-beta-x86_64-apple-darwin.tar.gz=0357ed5c9c8ccbe71f89695bffe1604dbd2f451472fc6ea8d8d2dfc93a703b30
+dist/2025-04-02/cargo-beta-x86_64-apple-darwin.tar.xz=6ce4f66b60609f58046138831ae3828ad1d58f8d0b2f515f153c96b690a0134f
+dist/2025-04-02/cargo-beta-x86_64-pc-windows-gnu.tar.gz=8fbf8506fc0c47bb30043c026107c51d6b548fa91320b5bbd2c608e191bdc007
+dist/2025-04-02/cargo-beta-x86_64-pc-windows-gnu.tar.xz=bb57df35e6d73b0b0bba58801d66febfed03f0b3f74085eb50ef8b5ea3fdbb40
+dist/2025-04-02/cargo-beta-x86_64-pc-windows-msvc.tar.gz=0bec5e9059c4b3035f636017c1586653d372f03969bcd4d80c0eaee52f01a2ac
+dist/2025-04-02/cargo-beta-x86_64-pc-windows-msvc.tar.xz=3f836d3027d7ed25655f43262b126311bf014629dadc4a860f00302bc468e752
+dist/2025-04-02/cargo-beta-x86_64-unknown-freebsd.tar.gz=0f60566416471c38350c12f066bb512eca65a66319f5ee7fdbb60464d70661fa
+dist/2025-04-02/cargo-beta-x86_64-unknown-freebsd.tar.xz=eae168df54ddfe95db669c205ae97baa902056722856fa174758ebd058168a95
+dist/2025-04-02/cargo-beta-x86_64-unknown-illumos.tar.gz=816eb91ac3858043f58075fc48fc2e90d0427c58b6283be589d337a7f0ddc9df
+dist/2025-04-02/cargo-beta-x86_64-unknown-illumos.tar.xz=faba548d376309b71bcdae49f7089705be951f72a84ef68362aa6d865d40ebf9
+dist/2025-04-02/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=1fe7e9d2c5a733acdaed418011c1fc31c3036e5299e8f9288ddeac43780fa35e
+dist/2025-04-02/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=7a39bd08e46d3e19da81c02ea3bb46bd1750a3ac1d1db8fb5db852cde14cdd72
+dist/2025-04-02/cargo-beta-x86_64-unknown-linux-musl.tar.gz=00df62b75e1811fd4fcc827b531e7ad94a73fcc37318d0aed28796d902b33568
+dist/2025-04-02/cargo-beta-x86_64-unknown-linux-musl.tar.xz=874084ab37814ddf50ef423e22f0721e5c24acd953ed02cf83432d2372606a5f
+dist/2025-04-02/cargo-beta-x86_64-unknown-netbsd.tar.gz=7b4467e398bd34f94912c56863ae83b45415bbf612b3be15624a6a410c27ff2a
+dist/2025-04-02/cargo-beta-x86_64-unknown-netbsd.tar.xz=75e7ac498a8e617bb907c26f2a3bba9a1e9a22af1c0946f88c7bd53c28790ffb
+dist/2025-04-02/clippy-beta-aarch64-apple-darwin.tar.gz=0f5a8a6a96b8785beae1fc9476374d060632dcc4c17a4335031425ee8e2dec48
+dist/2025-04-02/clippy-beta-aarch64-apple-darwin.tar.xz=aed266be1799ae3e95099d491c3b20b731b2094bc8388c6ac3e782667b58ca6f
+dist/2025-04-02/clippy-beta-aarch64-pc-windows-msvc.tar.gz=0ca97501432918d43aa9bed9b58cd4f1d0d738970e09d6c037ce967519b2b13f
+dist/2025-04-02/clippy-beta-aarch64-pc-windows-msvc.tar.xz=c64edd87358c1ecb9e01b204977edaf0307cc939a3dd3ae62f151c153ac2019b
+dist/2025-04-02/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7bfdd371ed44a32e50ecd6baf107796d5a77ca3cce0bd58bc5882afd98ca0edf
+dist/2025-04-02/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=cf49acab8153fb65867a9c44eabb7f156f85e9818b6f49453067ce0764036919
+dist/2025-04-02/clippy-beta-aarch64-unknown-linux-musl.tar.gz=bfb20f832ba30a4840f0d4898d27cf69b5717a78bd71b20270f8ddd66c48bc69
+dist/2025-04-02/clippy-beta-aarch64-unknown-linux-musl.tar.xz=54081690d35c39267a49d991e5e0c16043261b6969c49f23c2be44e46c3bfcdf
+dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=3d88b69d6c67c58b09be9d679cfbe8ee449b9de419e950edcffd4637ded46cac
+dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=67843ea0aeaab167029818669074e8bdc46a7e1c269a15580cdfe44a7d2ba96b
+dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=46e9efe50418a035ddabf9a6467b6b0ef20453816c4b6dfd46fa1342bdc42167
+dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=3b27dc434e88280bbc89f5c5ba6eb68ec5332b549b73f7f8d79feda9cbb49628
+dist/2025-04-02/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=670a6ce01ee6e5225b152a1357eba9a41cb47f04d08cdc8a0828eded4132aba1
+dist/2025-04-02/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=cf92bed8c784e9579c09305fd227df3992950c227bc844a9b09995828d62e2cc
+dist/2025-04-02/clippy-beta-i686-pc-windows-gnu.tar.gz=58238b6f4f8ad957a39c0eb63b45007d1c3f8c79e98307c7e5a531b7309a30f4
+dist/2025-04-02/clippy-beta-i686-pc-windows-gnu.tar.xz=e77c5215b3e96c59fa150330cb5144db66dac377fdad3be9c28f9fa07d9fb7cc
+dist/2025-04-02/clippy-beta-i686-pc-windows-msvc.tar.gz=7c65df8af1f6f4102ffbd7fdaec50c24f89f2631edd06642732f1b5c74558ab4
+dist/2025-04-02/clippy-beta-i686-pc-windows-msvc.tar.xz=eeb119d26e1e2ddd3ef72741158d75d0db254f6420fd729d34abe5d172c7d765
+dist/2025-04-02/clippy-beta-i686-unknown-linux-gnu.tar.gz=c43518b27adce17f06f89c70ab52ae4c94f1f7129a182c16f9bb28fbc8a5f40b
+dist/2025-04-02/clippy-beta-i686-unknown-linux-gnu.tar.xz=1d972c55d89cc01b7e408b4e24e8975bca29ff28578f224024a00f00d17c28b8
+dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=0d779bd9fcc5ed8e1db81a3a385bc0158c3903e5b0f0e4c99d172eee106a4f3e
+dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=5515e0678c081ddae45f3f0c3c7ae58cc2f7b1141e1557a39826bf1aa58a2480
+dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=e99599c1fd0cab2eb0e89dd8e37e90ee2106d602a3edb3473fd65768bb8f7b27
+dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=f346a801dee3734461eab4303469d31faaf3e8f0d733b854470722ed48c66276
+dist/2025-04-02/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=cd7b58e507d6695ada446ef9fa113a9588501832f4627b3e7cc0000a77c9265f
+dist/2025-04-02/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0a7073874663b4ce8eb47a0257ac0cf8049acb34703241466f1208489c4dbee0
+dist/2025-04-02/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=78d0b9581a7d79549bbb6a7e8984bf923a7b80bf6bb3979a90e90ceed8e66d33
+dist/2025-04-02/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=79069a26ed617a2a07eef7cf098d028cb0c172fc4a6dc99115a51862b1b8bea8
+dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=23c58421839105c88937ad90a92603b7fcd6d9e21f291ab8c419fce1663a20a5
+dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=b546706d28c46f5bd3799d6b42201962ec2e9d6baf8df2b66cfcf1bc42789036
+dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=31cf0d973eb3f0ca341a8d64c26b8b3b045b44b3c00d2497893dac6e44ebdeb4
+dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=8afd89866c41631d4f4ac4d8a06d943473af7a96b043f6112216a04863817820
+dist/2025-04-02/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=f08bf4ed1519e7c47f354a0d0b750933342314bacd4be761746666cf455cf74b
+dist/2025-04-02/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=e502f83f811c35e43df0a5e158d9eb61f60c9e1aacc75b588b2ba85022ca4b3e
+dist/2025-04-02/clippy-beta-s390x-unknown-linux-gnu.tar.gz=21bede57083544028238ef6c9d24cbf9194a35c88500f2d0c5d50e6f0ae79616
+dist/2025-04-02/clippy-beta-s390x-unknown-linux-gnu.tar.xz=670c0a293e1b01f331c2645b648c1df087da4c1b5d689f608279b1ba524cbaef
+dist/2025-04-02/clippy-beta-x86_64-apple-darwin.tar.gz=a6552e032c047203d5a9f5b767945c7a556be35468c42631c0c84cd049e24a8a
+dist/2025-04-02/clippy-beta-x86_64-apple-darwin.tar.xz=17a9e9ea8e0d6140080b7fa4e3c77ad1a7fde3c3179f26b0aabe34c3af73b58a
+dist/2025-04-02/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2ffa8663502f4c6bba049318c70e79c174fd717d45ab4427103fc11563be678f
+dist/2025-04-02/clippy-beta-x86_64-pc-windows-gnu.tar.xz=8c0a71f226b229f30a9acfbc1ab7c6bbedf692ef7b26737721a0518d3f1972ab
+dist/2025-04-02/clippy-beta-x86_64-pc-windows-msvc.tar.gz=463c7a5d2a11beaeb1e63bc769db89fb9996a0558da15b4e091befe982893711
+dist/2025-04-02/clippy-beta-x86_64-pc-windows-msvc.tar.xz=40241fa6e463df734096e0e910b414c83d8a4dc8706b7c712cc170844e59e3c6
+dist/2025-04-02/clippy-beta-x86_64-unknown-freebsd.tar.gz=6464044b05b326d8ea594a963e38a52a1e27e0f028704427c41ec5e93e3772d9
+dist/2025-04-02/clippy-beta-x86_64-unknown-freebsd.tar.xz=77cdeb1e838c3da1d01252481f7c06149b0b8e7df48c2a2ee5961f4550d7b662
+dist/2025-04-02/clippy-beta-x86_64-unknown-illumos.tar.gz=d51238e1ad2329b9309e94b40f3374788e2fda9bf47466841a841392835e8a5e
+dist/2025-04-02/clippy-beta-x86_64-unknown-illumos.tar.xz=6ad33945045790946fae843f63a805e60c09157e106ff342d3b99a201cd221e1
+dist/2025-04-02/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=64b4f85d9eb75172928b46540090128ce9eec00e275d9027f74d0d5d4106bd76
+dist/2025-04-02/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=b090383b4ebeae96fb340f0a363ee0276eb1f17a4f2a0f2ed81aff039f21bf78
+dist/2025-04-02/clippy-beta-x86_64-unknown-linux-musl.tar.gz=8d8025922c563bb1c872111722a4de298a8f85cd5be3e4cf753d44d6b8304de6
+dist/2025-04-02/clippy-beta-x86_64-unknown-linux-musl.tar.xz=ecf15ae9eb7dafe97afd69133f13364dac09d5e6edc35ddab91fb4ac32e17d42
+dist/2025-04-02/clippy-beta-x86_64-unknown-netbsd.tar.gz=c802af6a6f454b771046bd4a5207bdbe538cb6827becc9174dc229de5f874426
+dist/2025-04-02/clippy-beta-x86_64-unknown-netbsd.tar.xz=03d1e16eaf6f83f80e4cef8c7beebee97498135dd3138b97f97186b545edfb86
+dist/2025-04-02/rustfmt-nightly-aarch64-apple-darwin.tar.gz=c02047132bc7b48bbe930dfddb3afd31349eb042cb101a19d6e4360ea6e586ad
+dist/2025-04-02/rustfmt-nightly-aarch64-apple-darwin.tar.xz=cf825dfaeb4d97eb2819ff8e46360192f480960f6b516e328ef8a9493d413a9f
+dist/2025-04-02/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=588551cbfb62eb4ed4e5755fe6eb3e1499a79e24a8a75f448b10d9a2237c63db
+dist/2025-04-02/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=df666f179fcfccb316aeb1a5eb4c17710b23198176edb34ba8b98c88cb369098
+dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=b06f4aefa01300ef1827a29c9fcd2e4da0c13f3aad92b4c929f6e8811d53ab71
+dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=059a888b8db76f5a3054a9a78a131d79c49060deaf70b2e2f03a4fcab44ab536
+dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=f0117a7be9eefe70fbd2f0d3fc05c51f3a97d069dc99500520a5d0973178fc6a
+dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=f2fa87f1e814d0fb163146cf6a47d9375fec2c3778f76c33988acaa1665dacf7
+dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=fa53d4a6fb2ee3e1607d825afcc05063c0fa0dda1a3ede9a57e1ccc72cece8c4
+dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=3d785d982878f9bda4778cca0f9365947665849d5f7d2ee4794d8c28df3ab8c8
+dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=affb343357cd4c677cdeaf3b24698f20cfa15062cb63257aaa9bca3bd7baeeae
+dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6eb95c2021571a0c1ad3e3edf58fa4daa7711a9085e2ab61bc75799252183358
+dist/2025-04-02/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=1dffc39afb9210c77e6d45b68cb801247f00afdf33107963c82a83bd94d2225e
+dist/2025-04-02/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=2da28dd8ec76744a7629619f527196689eb35e9bc60f3a5965ed69486e44235d
+dist/2025-04-02/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5b1b39125106cdcbf12be9d5786900852f54eaa1429cabf28eeb68f96a008f90
+dist/2025-04-02/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=3f2ecb3787c82a8dae89929aca4f2f3af790f1ab3c698adf21dde21c919a4052
+dist/2025-04-02/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=eeb8b3f10f1cd75fac4e9e13dd1aee5941f38f1ff7fcfcaa69fcc3a42ea7c49a
+dist/2025-04-02/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=afd81cfd8d5fb37427c7eb2a1429c3b06d8daa1f42002c7230718fc56e132c47
+dist/2025-04-02/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=5eb0f065a5403645ebb6c01d7f27a763f9446b8a48db5b6ff962b6f7c0f3ea3b
+dist/2025-04-02/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=3576e2e8ecc563cfbc4b3f464d80f8e27f412b5eb267656dc5f0316a11a2d299
+dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=5e69db53a1161ad7616f9e50d1a7fef785840bdf0ba81757d0b6811078692921
+dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=ba9d18dd2d63bad1e2863c9e14bbc4bd282d03cb806d03011d2d61ce701d934f
+dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=b112f8c2e6ec011382c02a40ca07f30e1885a1396a7f2c30f099e56d756f2f54
+dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=42af68aa0b77306187d13ef881ee4327856f505a8a518f46244ffb17037f7e4e
+dist/2025-04-02/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=ed4277c9c8a27fdb97911bb9fbb46385b5fd807ac9338d31eecc3240bb0bc5c2
+dist/2025-04-02/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=4cf3a7a64edd09b5d8ad72af545c15013842072e70789d1741f845f27c60566d
+dist/2025-04-02/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=65d49556ac1abd1da9cb7c41e518f85213ee2b1f05559c917614937d4c0cada9
+dist/2025-04-02/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=535ea938d888ea12c139740e5d25ac4b82135b3274b8d86c3c59e36928922ec6
+dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9776e0c641ae8a229453fe1fbdaaae05ea0caf37bb4893a00fe86e5d63d1241a
+dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=bf73cfd35802b2706d0db96c854e8a4c45398297a59aef92226ac28d8bb69417
+dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=307012d0741898b3a2840ba3535832943ab6127f27323e587e1918b2023b37a2
+dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=79912529a393cb77c604f5a16d5b22611e938971656efd57fc5ef1980ffad35a
+dist/2025-04-02/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=854280cb3eeac146196ba30c8f3a010d568bf5bf9613d1870bd052a2aa3a03c0
+dist/2025-04-02/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=36e6cfc2b333cf077e3e1bf651acab4e6845330fa151848926d7b33fafa016f3
+dist/2025-04-02/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=19409bf4daa2e4d76c99659d7348f9a7dd4eb640c8bc81d93dc9170a1e51b7ba
+dist/2025-04-02/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=999346ff469e15507ec43c0b265a94b98ee99a0096d68ea0307a2280d138838f
+dist/2025-04-02/rustfmt-nightly-x86_64-apple-darwin.tar.gz=6a52a943d59edb9e6ed97643b01a2ca2f51abb6fba1b4c9b73f59646372aac01
+dist/2025-04-02/rustfmt-nightly-x86_64-apple-darwin.tar.xz=3701a72b39a31e31c9fe65afa660a507088dfe6039867a2019bfb69970872bad
+dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=c0dbe39a6dc72d96446312584055cfd75a4304c4859016ec7590d52813f0736c
+dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f9e8814cf2e0241bbe40bfafc62bb961d87060dd94c84fba8ea00b2992eafe2a
+dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=b9a2c923b6794b3462882a9f5b1579e2463024a72ff34cdf4bdfd8b0f51ee528
+dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=c5e8272c451a3d685842e07a996e8bdc305ccb02a02d39f7f4cc764be4b2adce
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=d47cb1e290f09795a04652f33afba39f80f3b6dcc4b570c14c75b1d945c78f0a
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=389ea9f755623dd3d887bbff71189f86d7397c82e2f8fe660c27784cf7c68a94
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=b49f6c211c51a50309ddd2bcb4c886ebeef47e5413e6399778157bc90a37ed0e
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=d53f55b6dba14bb2e2f90510c3e432781a8aad1f871d8f38795edf866ed4a4f3
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=2b8d77937298b23522ab9bd2f64a829f6faf1dccb87033f6006aa8c324474b47
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=0579d2a7c17cd585c49a42efe062466db777c1e7890f21b319234ee81c86ea39
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=65bc50db8fbe283e876b9ae7d6c15ff0461c1db8b3327f2992a99d21bcc3266c
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=120505da1a8cddfb3f549438a52b2c73c76a9f1c2f25709db13d61efd214d732
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=d19004b3f6b9fa446e23f540b21a8f314d3bbcca11f753c9a6fdaf4c7ae7a2de
+dist/2025-04-02/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=e7facb66daed07789015c2d5b092afde5dbb1349d06cd0f80ae8319437587723
+dist/2025-04-02/rustc-nightly-aarch64-apple-darwin.tar.gz=3783e0aa4450a6bb913fc9a9799950892e65c7af9a2c895419090072999a2305
+dist/2025-04-02/rustc-nightly-aarch64-apple-darwin.tar.xz=4d3a72db4cfcd7663803f1a0b193326e37c7faecc0c97c3903a17fbc0f7c8848
+dist/2025-04-02/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=c253308683fd394b1287a4eb9ca00cb8557bd7f7f91af8b087adccf9153a94eb
+dist/2025-04-02/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=63c30a1e523266dd6f8d6bb1525484f51fc6462bd7946900e0590b219f2a8b47
+dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=74d2313a732fc8401d62b9a8610bd9a25502f0372921c0e99d9d20f0cf8e3b19
+dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=a96db92f8c7cebe6e0d140a1853ecaa038e04975d62f17950e141d8ac2452536
+dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=250e2c21af9d4b284c7455668ebcc3d1e408c20cda1abf0ee69acac4c873e5ed
+dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=931714cf51d93fee5cc9465e9a0e9d34c771fe2aaae46994f3b00da4c95a8f54
+dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=28f993889175ba3feb78b458be5282b2564a7c9b96117fed071835ff7b47f43f
+dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=8645d1a7510cc13e2cd9abeffa71cbfb5f3a99990d27da2b05c336801a51c7f0
+dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=a86525223d8c5d67b0a92382b6ebce65761cdb83629e11bf29d625d688908d38
+dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=06a57a2c6298bb6e477d1e04922c626142bf96b2072684aecbbbf876bb4296f1
+dist/2025-04-02/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=a7fb3babdc244ea1f025f3033d13088c50696db8d6db29efcc6a78474a06769e
+dist/2025-04-02/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=b130a7efa1c2bdfa5ef51237d5233ab6bd8feade7dc596d120b6501b4766a569
+dist/2025-04-02/rustc-nightly-i686-pc-windows-gnu.tar.gz=ebb4dda0d1ced3ec5aa14b1ef38227628db92a87f45b817d4ce41ff026a687ec
+dist/2025-04-02/rustc-nightly-i686-pc-windows-gnu.tar.xz=43a69c9382b20249495824c149ffb5b5dae2ff7407c0c431859bc3e1f1ca4a7c
+dist/2025-04-02/rustc-nightly-i686-pc-windows-msvc.tar.gz=bf3eb550e148e89e7ff17be5e72ad0462d57f3c452bfdc46b80a1812ec2fe457
+dist/2025-04-02/rustc-nightly-i686-pc-windows-msvc.tar.xz=b2dde774c1ef573c6a889c2d78bbb98f535f22be4b20896797be2f10781f0eb4
+dist/2025-04-02/rustc-nightly-i686-unknown-linux-gnu.tar.gz=96d130960b0dc1d8fa54f53d22a8fa8cf5aa35d0b213071404122e4e714feab0
+dist/2025-04-02/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d743c6126151dd18624382a4228bf90af1239fc7fd97e763009b31666fb860fb
+dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=090ec673f24758b8a4d0ce7b8c58fc6015585bd8392e37760283ffbe6045298c
+dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c71ad975a15c440890a7358b5459b7ca6b9d5e1842dd353071467c2a3f841605
+dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=8806875cee039409632e8baf5433227af04bd07d015329d9512cc4f4879f687c
+dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=cebc3a4f1eb71e86e4e63f78e1c2f86fc98f7d23db1a3cb7e4c4d385e5591d51
+dist/2025-04-02/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=643dc0fe347a78a82321b5f47b41b09025856b6383ef67274ba3324879aae75e
+dist/2025-04-02/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=955018b90daf3797497dfc423aec731e8d0320b96dcf42db1705b761e1e0dd58
+dist/2025-04-02/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=aed278e57ffe0eb54328a9536607bc179806e0c2de9fccb9779a4517752899e5
+dist/2025-04-02/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=0b6e0305b13d867c677243b16613f62b07352038f5e7ad7e1865cc2d00168283
+dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=e10d8eee30be690aa2e6ff58ca554d47173086d5df8f0ea8581b3fd10d4cee0a
+dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=3ca3c258404dd8718321ed8a50aa6512fea9d810120db225a3fcfe56d7b83064
+dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=ddfc329b8932ad796c0eb7618632f9ae0c5ffb7a6093ea7d5cc4185fc0537f22
+dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=b4e82b64f2e934e17fc9b270295554a8bf0bd3d38ffffc66b367aad5bee3ad6f
+dist/2025-04-02/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=116d290065bd9e8ff2ca57440e94f773f68adf79aedba767159dfb92fe1a42b0
+dist/2025-04-02/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=6e1deb0c47bba4b56bbf1d04344e45f0490938455aee421629f2fcfd309eff64
+dist/2025-04-02/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=445f8a0ca579153b449fa0d36460227af68399c4227be76e4cbb3d65cef9055c
+dist/2025-04-02/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=d87bcac173e9800dc1c1b28e668a1b4c3616029d0ca53adfa4ac382733610193
+dist/2025-04-02/rustc-nightly-x86_64-apple-darwin.tar.gz=4342b89aed19f409df56bfac3d6ac071a02cb6839a52d19fdff9d10cc1d9f540
+dist/2025-04-02/rustc-nightly-x86_64-apple-darwin.tar.xz=cb787327895f275e6f9025bb38c6337492c839310931b8c7ba39743813621701
+dist/2025-04-02/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=6cddd0d3cf18780b36776fd0324643a36b3294923531a741cc763516c8238caf
+dist/2025-04-02/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=cefc15752bd84b290f50b958b96feb0134d420a10c6f36791424c762cda08abc
+dist/2025-04-02/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=731e968787044081453a559a95579435654b47f91a9b7f94579ac007ed3e4cf9
+dist/2025-04-02/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=3d9b173043aed73aa3ab1fa0b14d0ce2149a4943f4bb10aa1e31af619afe0eed
+dist/2025-04-02/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c0df2f0a354d2d657d8ec8091bc094060321b343c8e7bb8e4315cfe042dacfc3
+dist/2025-04-02/rustc-nightly-x86_64-unknown-freebsd.tar.xz=8933bc0361484ac7c6b226defaea73eda5c4e10462e7ea54052c7e1d370e48c0
+dist/2025-04-02/rustc-nightly-x86_64-unknown-illumos.tar.gz=5887f913ac80dfe9826619227c66eb234a2b4848e6bc4f41c6fdd8102bf981e9
+dist/2025-04-02/rustc-nightly-x86_64-unknown-illumos.tar.xz=4a54b8b09eba43df0d99fb6e03177cf8ba2214a5810be52ac33ee3d9d33e98bc
+dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=1c0bb76acd7944804d52c3139f4dcf154d3221cdeb300bb6b9bca726cd6ad30f
+dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=e67a33440c3e021ff2dd41add0fb05db6c0e8ae68bd30d33e8b3185b0bb7191b
+dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=0ea7e17d7bb67d6a6c4b2f864aaffcd96512f15f17f0acc63751eb1df6c486a7
+dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=b73d37b704ab58921172cc561f5598db6a504dcd4d7980966f7c26caaf6d3594
+dist/2025-04-02/rustc-nightly-x86_64-unknown-netbsd.tar.gz=986f6c594d37bcbd3833e053640ba8775f68d26a65c5618386654ef55d7b3542
+dist/2025-04-02/rustc-nightly-x86_64-unknown-netbsd.tar.xz=c0d9a88c30d2ab38ec3a11fabb5515ed9bc3ac1a8e35a438d68bf7ff82f6b843
\ No newline at end of file
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 94c170d..f5a8e3d 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -25,6 +25,7 @@
[dependencies]
clippy_config = { path = "clippy_config" }
clippy_lints = { path = "clippy_lints" }
+clippy_utils = { path = "clippy_utils" }
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
tempfile = { version = "3.3", optional = true }
termize = "0.1"
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
index cd38aed..7fab97d 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -1,10 +1,10 @@
use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, MsrvStack};
+use clippy_utils::sym;
use rustc_ast::AttrStyle;
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
-use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
// check cfg_attr
@@ -18,7 +18,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
// check for `rustfmt_skip` and `rustfmt::skip`
&& let Some(skip_item) = &items[1].meta_item()
- && (skip_item.has_name(sym!(rustfmt_skip))
+ && (skip_item.has_name(sym::rustfmt_skip)
|| skip_item
.path
.segments
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index e3e081c..1cb43ab 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -2,10 +2,10 @@
use super::utils::{is_lint_level, is_word, namespace_and_lint};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{SpanRangeExt, first_line_of_span};
+use clippy_utils::sym;
use rustc_ast::{Attribute, Item, ItemKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
-use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
@@ -61,7 +61,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
if is_word(lint, sym::unused_imports) && skip_unused_imports {
return;
}
- if is_word(lint, sym!(unused_extern_crates)) {
+ if is_word(lint, sym::unused_extern_crates) {
return;
}
},
diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
index adac2f2..ad18c70 100644
--- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
@@ -53,7 +53,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
.not_trait()
.filter(|trait_id| implements_trait(cx, ty, *trait_id, &[]))
.and_then(|trait_id| {
- cx.tcx.associated_items(trait_id).find_by_name_and_kind(
+ cx.tcx.associated_items(trait_id).find_by_ident_and_kind(
cx.tcx,
Ident::from_str("Output"),
ty::AssocKind::Type,
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index f6c10da..bf549dc 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -38,7 +38,7 @@ pub fn check(
// of all `#[test]` attributes in not ignored code examples
fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
rustc_driver::catch_fatal_errors(|| {
- rustc_span::create_session_globals_then(edition, None, || {
+ rustc_span::create_session_globals_then(edition, &[], None, || {
let mut test_attr_spans = vec![];
let filename = FileName::anon_source_code(&code);
diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
index 041f622..4495aeb 100644
--- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
@@ -22,8 +22,8 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
&& let Some(did) = trait_item_def_id_of_impl(items, item.owner_id)
&& !is_from_ignored_trait(trait_ref, ignored_traits)
{
- let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id);
- let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied();
+ let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
+ let mut default_param_idents_iter = cx.tcx.fn_arg_idents(did).iter().copied();
let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter);
if !renames.0.is_empty() {
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 56ff7e2..239ee6c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -238,7 +238,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
.instantiate_bound_regions_with_erased(sig.rebind(search_ty))
.kind()
&& let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
- && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_name_and_kind(
+ && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_ident_and_kind(
cx.tcx,
Ident::with_dummy_span(sym::Item),
AssocKind::Type,
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index bcb0f83..2ba70c4 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -3,6 +3,7 @@
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
+#![feature(macro_metavar_expr)]
#![feature(macro_metavar_expr_concat)]
#![feature(let_chains)]
#![feature(never_type)]
@@ -74,6 +75,7 @@
pub mod source;
pub mod str_utils;
pub mod sugg;
+pub mod sym;
pub mod ty;
pub mod usage;
pub mod visitors;
@@ -126,7 +128,7 @@
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{Ident, Symbol, kw};
-use rustc_span::{InnerSpan, Span, sym};
+use rustc_span::{InnerSpan, Span};
use visitors::{Visitable, for_each_unconsumed_temporary};
use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs
new file mode 100644
index 0000000..9cc72a5
--- /dev/null
+++ b/src/tools/clippy/clippy_utils/src/sym.rs
@@ -0,0 +1,23 @@
+#![allow(non_upper_case_globals)]
+
+use rustc_span::symbol::{Symbol, PREDEFINED_SYMBOLS_COUNT};
+
+pub use rustc_span::sym::*;
+
+macro_rules! generate {
+ ($($sym:ident,)*) => {
+ /// To be supplied to `rustc_interface::Config`
+ pub const EXTRA_SYMBOLS: &[&str] = &[
+ $(stringify!($sym),)*
+ ];
+
+ $(
+ pub const $sym: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
+ )*
+ };
+}
+
+generate! {
+ rustfmt_skip,
+ unused_extern_crates,
+}
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 6fdf4c2..29cbf62 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -1109,7 +1109,7 @@ fn helper<'tcx>(
assoc_ty: Symbol,
args: GenericArgsRef<'tcx>,
) -> Option<AliasTy<'tcx>> {
- let Some(assoc_item) = tcx.associated_items(container_id).find_by_name_and_kind(
+ let Some(assoc_item) = tcx.associated_items(container_id).find_by_ident_and_kind(
tcx,
Ident::with_dummy_span(assoc_ty),
AssocKind::Type,
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index e4092bc..df9c4e8e 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -160,6 +160,7 @@ fn config(&mut self, config: &mut interface::Config) {
clippy_lints::register_lints(lint_store, conf);
clippy_lints::register_pre_expansion_lints(lint_store, conf);
}));
+ config.extra_symbols = clippy_utils::sym::EXTRA_SYMBOLS.into();
// FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
// run on the unoptimized MIR. On the other hand this results in some false negatives. If
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 06e618c..3db34ed 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "compiletest"
version = "0.0.0"
-edition = "2021"
+edition = "2024"
[lib]
doctest = false
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 36218b2..6750b52 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -395,6 +395,7 @@ pub struct Config {
pub target_cfgs: OnceLock<TargetCfgs>,
pub builtin_cfg_names: OnceLock<HashSet<String>>,
+ pub supported_crate_types: OnceLock<HashSet<String>>,
pub nocapture: bool,
@@ -472,6 +473,11 @@ pub fn builtin_cfg_names(&self) -> &HashSet<String> {
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
}
+ /// Get the list of crate types that the target platform supports.
+ pub fn supported_crate_types(&self) -> &HashSet<String> {
+ self.supported_crate_types.get_or_init(|| supported_crate_types(self))
+ }
+
pub fn has_threads(&self) -> bool {
// Wasm targets don't have threads unless `-threads` is in the target
// name, such as `wasm32-wasip1-threads`.
@@ -745,6 +751,31 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
.collect()
}
+pub const KNOWN_CRATE_TYPES: &[&str] =
+ &["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
+
+fn supported_crate_types(config: &Config) -> HashSet<String> {
+ let crate_types: HashSet<_> = rustc_output(
+ config,
+ &["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
+ Default::default(),
+ )
+ .lines()
+ .map(|l| l.to_string())
+ .collect();
+
+ for crate_type in crate_types.iter() {
+ assert!(
+ KNOWN_CRATE_TYPES.contains(&crate_type.as_str()),
+ "unexpected crate type `{}`: known crate types are {:?}",
+ crate_type,
+ KNOWN_CRATE_TYPES
+ );
+ }
+
+ crate_types
+}
+
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs
index 20e3c8d..5126e55 100644
--- a/src/tools/compiletest/src/debuggers.rs
+++ b/src/tools/compiletest/src/debuggers.rs
@@ -40,7 +40,9 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
//
// we should figure out how to lift this restriction! (run them all
// on different ports allocated dynamically).
- env::set_var("RUST_TEST_THREADS", "1");
+ //
+ // SAFETY: at this point we are still single-threaded.
+ unsafe { env::set_var("RUST_TEST_THREADS", "1") };
}
Some(Arc::new(Config { debugger: Some(Debugger::Gdb), ..config.clone() }))
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index b2ad5a3..086a8a6 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -22,6 +22,7 @@
"dont-check-compiler-stderr",
"dont-check-compiler-stdout",
"dont-check-failure-status",
+ "dont-require-annotations",
"edition",
"error-pattern",
"exact-llvm-major-version",
@@ -132,6 +133,7 @@
"min-llvm-version",
"min-system-llvm-version",
"needs-asm-support",
+ "needs-crate-type",
"needs-deterministic-layouts",
"needs-dlltool",
"needs-dynamic-linking",
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index 9b59e49..64d68eb 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -8,7 +8,7 @@
use regex::Regex;
use tracing::*;
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ErrorKind {
Help,
Error,
@@ -40,6 +40,15 @@ fn from_user_str(s: &str) -> Option<ErrorKind> {
_ => return None,
})
}
+
+ pub fn expect_from_user_str(s: &str) -> ErrorKind {
+ ErrorKind::from_user_str(s).unwrap_or_else(|| {
+ panic!(
+ "unexpected diagnostic kind `{s}`, expected \
+ `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
+ )
+ })
+ }
}
impl fmt::Display for ErrorKind {
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index a0178f4..3406e87 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -1,4 +1,4 @@
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::File;
use std::io::BufReader;
@@ -11,6 +11,7 @@
use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
+use crate::errors::ErrorKind;
use crate::executor::{CollectedTestDesc, ShouldPanic};
use crate::header::auxiliary::{AuxProps, parse_and_update_aux};
use crate::header::needs::CachedNeedsConditions;
@@ -196,6 +197,8 @@ pub struct TestProps {
/// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios
/// that don't otherwise want/need `-Z build-std`.
pub add_core_stubs: bool,
+ /// Whether line annotatins are required for the given error kind.
+ pub require_annotations: HashMap<ErrorKind, bool>,
}
mod directives {
@@ -212,6 +215,7 @@ mod directives {
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
+ pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations";
pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
pub const PRETTY_MODE: &'static str = "pretty-mode";
pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
@@ -297,6 +301,13 @@ pub fn new() -> Self {
no_auto_check_cfg: false,
has_enzyme: false,
add_core_stubs: false,
+ require_annotations: HashMap::from([
+ (ErrorKind::Help, true),
+ (ErrorKind::Note, true),
+ (ErrorKind::Error, true),
+ (ErrorKind::Warning, true),
+ (ErrorKind::Suggestion, false),
+ ]),
}
}
@@ -378,14 +389,22 @@ fn split_flags(flags: &str) -> Vec<String> {
}
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
- self.compile_flags.extend(split_flags(&flags));
+ let flags = split_flags(&flags);
+ for flag in &flags {
+ if flag == "--edition" || flag.starts_with("--edition=") {
+ panic!("you must use `//@ edition` to configure the edition");
+ }
+ }
+ self.compile_flags.extend(flags);
}
if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() {
panic!("`compiler-flags` directive should be spelled `compile-flags`");
}
if let Some(edition) = config.parse_edition(ln) {
- self.compile_flags.push(format!("--edition={}", edition.trim()));
+ // The edition is added at the start, since flags from //@compile-flags must
+ // be passed to rustc last.
+ self.compile_flags.insert(0, format!("--edition={}", edition.trim()));
has_edition = true;
}
@@ -441,7 +460,7 @@ fn split_flags(flags: &str) -> Vec<String> {
ln,
UNSET_EXEC_ENV,
&mut self.unset_exec_env,
- |r| r,
+ |r| r.trim().to_owned(),
);
config.push_name_value_directive(
ln,
@@ -453,7 +472,7 @@ fn split_flags(flags: &str) -> Vec<String> {
ln,
UNSET_RUSTC_ENV,
&mut self.unset_rustc_env,
- |r| r,
+ |r| r.trim().to_owned(),
);
config.push_name_value_directive(
ln,
@@ -570,6 +589,13 @@ fn split_flags(flags: &str) -> Vec<String> {
config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg);
self.update_add_core_stubs(ln, config);
+
+ if let Some(err_kind) =
+ config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
+ {
+ self.require_annotations
+ .insert(ErrorKind::expect_from_user_str(&err_kind), false);
+ }
},
);
@@ -606,7 +632,9 @@ fn split_flags(flags: &str) -> Vec<String> {
}
if let (Some(edition), false) = (&config.edition, has_edition) {
- self.compile_flags.push(format!("--edition={}", edition));
+ // The edition is added at the start, since flags from //@compile-flags must be passed
+ // to rustc last.
+ self.compile_flags.insert(0, format!("--edition={}", edition));
}
}
@@ -979,16 +1007,13 @@ fn parse_and_update_revisions(&self, testfile: &Path, line: &str, existing: &mut
fn parse_env(nv: String) -> (String, String) {
// nv is either FOO or FOO=BAR
- let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
-
- match strs.len() {
- 1 => (strs.pop().unwrap(), String::new()),
- 2 => {
- let end = strs.pop().unwrap();
- (strs.pop().unwrap(), end)
- }
- n => panic!("Expected 1 or 2 strings, not {}", n),
- }
+ // FIXME(Zalathar): The form without `=` seems to be unused; should
+ // we drop support for it?
+ let (name, value) = nv.split_once('=').unwrap_or((&nv, ""));
+ // Trim whitespace from the name, so that `//@ exec-env: FOO=BAR`
+ // sees the name as `FOO` and not ` FOO`.
+ let name = name.trim();
+ (name.to_owned(), value.to_owned())
}
fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 12f0790..2ace40c 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -1,4 +1,4 @@
-use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
+use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::header::{IgnoreDecision, llvm_has_libzstd};
pub(super) fn handle_needs(
@@ -6,7 +6,7 @@ pub(super) fn handle_needs(
config: &Config,
ln: &str,
) -> IgnoreDecision {
- // Note thet we intentionally still put the needs- prefix here to make the file show up when
+ // Note that we intentionally still put the needs- prefix here to make the file show up when
// grepping for a directive name, even though we could technically strip that.
let needs = &[
Need {
@@ -224,6 +224,50 @@ pub(super) fn handle_needs(
}
}
+ // FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
+ if name == "needs-crate-type" {
+ let Some(rest) = rest else {
+ return IgnoreDecision::Error {
+ message:
+ "expected `needs-crate-type` to have a comma-separated list of crate types"
+ .to_string(),
+ };
+ };
+
+ // Expect directive value to be a list of comma-separated crate-types.
+ let specified_crate_types = rest
+ .split(',')
+ .map(|crate_type| crate_type.trim())
+ .map(ToString::to_string)
+ .collect::<Vec<String>>();
+
+ for crate_type in &specified_crate_types {
+ if !KNOWN_CRATE_TYPES.contains(&crate_type.as_str()) {
+ return IgnoreDecision::Error {
+ message: format!(
+ "unknown crate type specified in `needs-crate-type`: `{crate_type}` is not \
+ a known crate type, known values are `{:?}`",
+ KNOWN_CRATE_TYPES
+ ),
+ };
+ }
+ }
+
+ let satisfies_all_crate_types = specified_crate_types
+ .iter()
+ .all(|specified| config.supported_crate_types().contains(specified));
+ if satisfies_all_crate_types {
+ return IgnoreDecision::Continue;
+ } else {
+ return IgnoreDecision::Ignore {
+ reason: format!(
+ "skipping test as target does not support all of the crate types `{:?}`",
+ specified_crate_types
+ ),
+ };
+ }
+ }
+
if !name.starts_with("needs-") {
return IgnoreDecision::Continue;
}
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index ff6bc49..f3461f3 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -459,9 +459,6 @@ fn profiler_runtime() {
#[test]
fn asm_support() {
let asms = [
- #[cfg(bootstrap)]
- ("avr-unknown-gnu-atmega328", false),
- #[cfg(not(bootstrap))]
("avr-none", false),
("i686-unknown-netbsd", true),
("riscv32gc-unknown-linux-gnu", true),
@@ -905,3 +902,41 @@ fn test_rustc_abi() {
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
}
+
+#[test]
+fn test_supported_crate_types() {
+ // Basic assumptions check on under-test compiler's `--print=supported-crate-types` output based
+ // on knowledge about the cherry-picked `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown`
+ // targets. Also smoke tests the `needs-crate-type` directive itself.
+
+ use std::collections::HashSet;
+
+ let config = cfg().target("x86_64-unknown-linux-gnu").build();
+ assert_eq!(
+ config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
+ HashSet::from(["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]),
+ );
+ assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
+ assert!(!check_ignore(&config, "//@ needs-crate-type: dylib"));
+ assert!(!check_ignore(
+ &config,
+ "//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
+ ));
+
+ let config = cfg().target("wasm32-unknown-unknown").build();
+ assert_eq!(
+ config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
+ HashSet::from(["bin", "cdylib", "lib", "rlib", "staticlib"]),
+ );
+
+ // rlib is supported
+ assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
+ // dylib is not
+ assert!(check_ignore(&config, "//@ needs-crate-type: dylib"));
+ // If multiple crate types are specified, then all specified crate types need to be supported.
+ assert!(check_ignore(&config, "//@ needs-crate-type: cdylib, dylib"));
+ assert!(check_ignore(
+ &config,
+ "//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
+ ));
+}
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 782f6e0..720663b 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -431,6 +431,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
target_cfgs: OnceLock::new(),
builtin_cfg_names: OnceLock::new(),
+ supported_crate_types: OnceLock::new(),
nocapture: matches.opt_present("no-capture"),
@@ -529,10 +530,14 @@ pub fn run_tests(config: Arc<Config>) {
}
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
- env::set_var("__COMPAT_LAYER", "RunAsInvoker");
+ //
+ // SAFETY: at this point we're still single-threaded.
+ unsafe { env::set_var("__COMPAT_LAYER", "RunAsInvoker") };
- // Let tests know which target they're running as
- env::set_var("TARGET", &config.target);
+ // Let tests know which target they're running as.
+ //
+ // SAFETY: at this point we're still single-threaded.
+ unsafe { env::set_var("TARGET", &config.target) };
let mut configs = Vec::new();
if let Mode::DebugInfo = config.mode {
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index 7b12ba9..653b125 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -6,6 +6,7 @@
/// This fixes issue #7772.
#[cfg(target_vendor = "apple")]
#[allow(non_camel_case_types)]
+// FIXME(#139616): document caller contract.
pub unsafe fn raise_fd_limit() {
use std::ptr::null_mut;
use std::{cmp, io};
@@ -21,8 +22,10 @@ pub unsafe fn raise_fd_limit() {
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
- if libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, null_mut(), 0)
- != 0
+ // FIXME(#139616): justify why this is sound.
+ if unsafe {
+ libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, null_mut(), 0)
+ } != 0
{
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling sysctl: {}", err);
@@ -30,7 +33,8 @@ pub unsafe fn raise_fd_limit() {
// Fetch the current resource limits
let mut rlim = libc::rlimit { rlim_cur: 0, rlim_max: 0 };
- if libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) != 0 {
+ // FIXME(#139616): justify why this is sound.
+ if unsafe { libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) } != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling getrlimit: {}", err);
}
@@ -41,7 +45,8 @@ pub unsafe fn raise_fd_limit() {
rlim.rlim_cur = cmp::min(maxfiles as libc::rlim_t, rlim.rlim_max);
// Set our newly-increased resource limit.
- if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 {
+ // FIXME(#139616): justify why this is sound.
+ if unsafe { libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) } != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling setrlimit: {}", err);
}
diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs
index 28ca558..2213dd0 100644
--- a/src/tools/compiletest/src/read2.rs
+++ b/src/tools/compiletest/src/read2.rs
@@ -165,6 +165,7 @@ pub fn read2(
mut err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
+ // FIXME(#139616): justify why this is sound.
unsafe {
libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
@@ -175,6 +176,7 @@ pub fn read2(
let mut out = Vec::new();
let mut err = Vec::new();
+ // FIXME(#139616): justify why this is sound.
let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
fds[0].fd = out_pipe.as_raw_fd();
fds[0].events = libc::POLLIN;
@@ -185,6 +187,7 @@ pub fn read2(
while nfds > 0 {
// wait for either pipe to become readable using `select`
+ // FIXME(#139616): justify why this is sound.
let r = unsafe { libc::poll(fds.as_mut_ptr(), nfds, -1) };
if r == -1 {
let err = io::Error::last_os_error();
@@ -256,6 +259,7 @@ pub fn read2(
port.add_handle(0, &out_pipe)?;
port.add_handle(1, &err_pipe)?;
+ // FIXME(#139616): justify why this is sound.
unsafe {
let mut out_pipe = Pipe::new(out_pipe, &mut out);
let mut err_pipe = Pipe::new(err_pipe, &mut err);
@@ -284,18 +288,23 @@ pub fn read2(
}
impl<'a> Pipe<'a> {
+ // FIXME(#139616): document caller contract.
unsafe fn new<P: IntoRawHandle>(p: P, dst: &'a mut Vec<u8>) -> Pipe<'a> {
Pipe {
dst,
- pipe: NamedPipe::from_raw_handle(p.into_raw_handle()),
+ // FIXME(#139616): justify why this is sound.
+ pipe: unsafe { NamedPipe::from_raw_handle(p.into_raw_handle()) },
overlapped: Overlapped::zero(),
done: false,
}
}
+ // FIXME(#139616): document caller contract.
unsafe fn read(&mut self) -> io::Result<()> {
- let dst = slice_to_end(self.dst);
- match self.pipe.read_overlapped(dst, self.overlapped.raw()) {
+ // FIXME(#139616): justify why this is sound.
+ let dst = unsafe { slice_to_end(self.dst) };
+ // FIXME(#139616): justify why this is sound.
+ match unsafe { self.pipe.read_overlapped(dst, self.overlapped.raw()) } {
Ok(_) => Ok(()),
Err(e) => {
if e.raw_os_error() == Some(ERROR_BROKEN_PIPE.0 as i32) {
@@ -308,15 +317,18 @@ unsafe fn read(&mut self) -> io::Result<()> {
}
}
+ // FIXME(#139616): document caller contract.
unsafe fn complete(&mut self, status: &CompletionStatus) {
let prev = self.dst.len();
- self.dst.set_len(prev + status.bytes_transferred() as usize);
+ // FIXME(#139616): justify why this is sound.
+ unsafe { self.dst.set_len(prev + status.bytes_transferred() as usize) };
if status.bytes_transferred() == 0 {
self.done = true;
}
}
}
+ // FIXME(#139616): document caller contract.
unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
if v.capacity() == 0 {
v.reserve(16);
@@ -324,6 +336,12 @@ unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
if v.capacity() == v.len() {
v.reserve(1);
}
- slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize), v.capacity() - v.len())
+ // FIXME(#139616): justify why this is sound.
+ unsafe {
+ slice::from_raw_parts_mut(
+ v.as_mut_ptr().offset(v.len() as isize),
+ v.capacity() - v.len(),
+ )
+ }
}
}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 08fccb7c..208d328 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -177,6 +177,7 @@ pub fn compute_stamp_hash(config: &Config) -> String {
let mut hash = DefaultHasher::new();
config.stage_id.hash(&mut hash);
config.run.hash(&mut hash);
+ config.edition.hash(&mut hash);
match config.debugger {
Some(Debugger::Cdb) => {
@@ -445,8 +446,8 @@ fn print_source(&self, read_from: ReadFrom, pretty_type: &str) -> ProcRes {
self.compose_and_run(
rustc,
- self.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ self.config.compile_lib_path.as_path(),
+ Some(aux_dir.as_path()),
src,
)
}
@@ -709,10 +710,6 @@ fn check_expected_errors(&self, expected_errors: Vec<errors::Error>, proc_res: &
self.testpaths.file.display().to_string()
};
- // If the testcase being checked contains at least one expected "help"
- // message, then we'll ensure that all "help" messages are expected.
- // Otherwise, all "help" messages reported by the compiler will be ignored.
- // This logic also applies to "note" messages.
let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help));
let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note));
@@ -800,9 +797,7 @@ fn check_expected_errors(&self, expected_errors: Vec<errors::Error>, proc_res: &
}
/// Returns `true` if we should report an error about `actual_error`,
- /// which did not match any of the expected error. We always require
- /// errors/warnings to be explicitly listed, but only require
- /// helps/notes if there are explicit helps/notes given.
+ /// which did not match any of the expected error.
fn is_unexpected_compiler_message(
&self,
actual_error: &Error,
@@ -810,12 +805,16 @@ fn is_unexpected_compiler_message(
expect_note: bool,
) -> bool {
actual_error.require_annotation
- && match actual_error.kind {
- Some(ErrorKind::Help) => expect_help,
- Some(ErrorKind::Note) => expect_note,
- Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true,
- Some(ErrorKind::Suggestion) | None => false,
- }
+ && actual_error.kind.map_or(false, |err_kind| {
+ // If the test being checked doesn't contain any "help" or "note" annotations, then
+ // we don't require annotating "help" or "note" (respecively) diagnostics at all.
+ let default_require_annotations = self.props.require_annotations[&err_kind];
+ match err_kind {
+ ErrorKind::Help => expect_help && default_require_annotations,
+ ErrorKind::Note => expect_note && default_require_annotations,
+ _ => default_require_annotations,
+ }
+ })
}
fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit {
@@ -970,16 +969,16 @@ fn exec_compiled_test_general(
delete_after_success: bool,
) -> ProcRes {
let prepare_env = |cmd: &mut Command| {
- for key in &self.props.unset_exec_env {
- cmd.env_remove(key);
- }
-
for (key, val) in &self.props.exec_env {
cmd.env(key, val);
}
for (key, val) in env_extra {
cmd.env(key, val);
}
+
+ for key in &self.props.unset_exec_env {
+ cmd.env_remove(key);
+ }
};
let proc_res = match &*self.config.target {
@@ -1022,8 +1021,8 @@ fn exec_compiled_test_general(
self.compose_and_run(
test_client,
- self.config.run_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ self.config.run_lib_path.as_path(),
+ Some(aux_dir.as_path()),
None,
)
}
@@ -1037,8 +1036,8 @@ fn exec_compiled_test_general(
self.compose_and_run(
wr_run,
- self.config.run_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ self.config.run_lib_path.as_path(),
+ Some(aux_dir.as_path()),
None,
)
}
@@ -1052,8 +1051,8 @@ fn exec_compiled_test_general(
self.compose_and_run(
program,
- self.config.run_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ self.config.run_lib_path.as_path(),
+ Some(aux_dir.as_path()),
None,
)
}
@@ -1199,8 +1198,8 @@ fn compose_and_run_compiler(
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
self.compose_and_run(
rustc,
- self.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ self.config.compile_lib_path.as_path(),
+ Some(aux_dir.as_path()),
input,
)
}
@@ -1221,8 +1220,7 @@ fn build_minicore(&self) -> PathBuf {
rustc.args(&["--crate-type", "rlib"]);
rustc.arg("-Cpanic=abort");
- let res =
- self.compose_and_run(rustc, self.config.compile_lib_path.to_str().unwrap(), None, None);
+ let res = self.compose_and_run(rustc, self.config.compile_lib_path.as_path(), None, None);
if !res.status.success() {
self.fatal_proc_rec(
&format!(
@@ -1334,8 +1332,8 @@ fn build_auxiliary(
let auxres = aux_cx.compose_and_run(
aux_rustc,
- aux_cx.config.compile_lib_path.to_str().unwrap(),
- Some(aux_dir.to_str().unwrap()),
+ aux_cx.config.compile_lib_path.as_path(),
+ Some(aux_dir.as_path()),
None,
);
if !auxres.status.success() {
@@ -1375,8 +1373,8 @@ fn read2_abbreviated(&self, child: Child) -> (Output, Truncated) {
fn compose_and_run(
&self,
mut command: Command,
- lib_path: &str,
- aux_path: Option<&str>,
+ lib_path: &Path,
+ aux_path: Option<&Path>,
input: Option<String>,
) -> ProcRes {
let cmdline = {
@@ -1808,7 +1806,7 @@ fn split_maybe_args(&self, argstr: &Option<String>) -> Vec<OsString> {
}
}
- fn make_cmdline(&self, command: &Command, libpath: &str) -> String {
+ fn make_cmdline(&self, command: &Command, libpath: &Path) -> String {
use crate::util;
// Linux and mac don't require adjusting the library search path
@@ -1821,7 +1819,7 @@ fn lib_path_cmd_prefix(path: &str) -> String {
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
}
- format!("{} {:?}", lib_path_cmd_prefix(libpath), command)
+ format!("{} {:?}", lib_path_cmd_prefix(libpath.to_str().unwrap()), command)
}
}
@@ -1982,7 +1980,8 @@ fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
// Add custom flags supplied by the `filecheck-flags:` test header.
filecheck.args(&self.props.filecheck_flags);
- self.compose_and_run(filecheck, "", None, None)
+ // FIXME(jieyouxu): don't pass an empty Path
+ self.compose_and_run(filecheck, Path::new(""), None, None)
}
fn charset() -> &'static str {
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 170b8a8..50e733c 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -104,7 +104,7 @@ fn run_debuginfo_cdb_test_no_opt(&self) {
let debugger_run_result = self.compose_and_run(
cdb,
- self.config.run_lib_path.to_str().unwrap(),
+ self.config.run_lib_path.as_path(),
None, // aux_path
None, // input
);
@@ -241,7 +241,8 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
let cmdline = {
let mut gdb = Command::new(&format!("{}-gdb", self.config.target));
gdb.args(debugger_opts);
- let cmdline = self.make_cmdline(&gdb, "");
+ // FIXME(jieyouxu): don't pass an empty Path
+ let cmdline = self.make_cmdline(&gdb, Path::new(""));
logv(self.config, format!("executing {}", cmdline));
cmdline
};
@@ -340,7 +341,7 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
debugger_run_result =
- self.compose_and_run(gdb, self.config.run_lib_path.to_str().unwrap(), None, None);
+ self.compose_and_run(gdb, self.config.run_lib_path.as_path(), None, None);
}
if !debugger_run_result.status.success() {
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index b8100d0..0c6f4a3 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -39,31 +39,31 @@
[[package]]
name = "annotate-snippets"
-version = "0.11.4"
+version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24e35ed54e5ea7997c14ed4c70ba043478db1112e98263b3b035907aa197d991"
+checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4"
dependencies = [
"anstyle",
- "unicode-width",
+ "unicode-width 0.2.0",
]
[[package]]
name = "anstyle"
-version = "1.0.8"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anyhow"
-version = "1.0.86"
+version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "autocfg"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
@@ -82,15 +82,15 @@
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bstr"
-version = "1.10.0"
+version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
+checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
dependencies = [
"memchr",
"regex-automata",
@@ -98,25 +98,25 @@
]
[[package]]
-name = "byteorder"
-version = "1.5.0"
+name = "bumpalo"
+version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "camino"
-version = "1.1.7"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
+checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
dependencies = [
"serde",
]
@@ -132,14 +132,14 @@
"semver",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
name = "cc"
-version = "1.1.22"
+version = "1.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
dependencies = [
"shlex",
]
@@ -152,18 +152,18 @@
[[package]]
name = "chrono"
-version = "0.4.38"
+version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"num-traits",
]
[[package]]
name = "chrono-tz"
-version = "0.10.0"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd6dd8046d00723a59a2f8c5f295c515b9bb9a331ee4f8f3d4dd49e428acd3b6"
+checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3"
dependencies = [
"chrono",
"chrono-tz-build",
@@ -172,9 +172,9 @@
[[package]]
name = "chrono-tz-build"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94fea34d77a245229e7746bd2beb786cd2a896f306ff491fb8cecb3074b10a7"
+checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402"
dependencies = [
"parse-zoneinfo",
"phf_codegen",
@@ -219,12 +219,12 @@
[[package]]
name = "colored"
-version = "2.1.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
+checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
@@ -235,40 +235,40 @@
[[package]]
name = "console"
-version = "0.15.8"
+version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
+checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
dependencies = [
"encode_unicode",
- "lazy_static",
"libc",
- "unicode-width",
- "windows-sys 0.52.0",
+ "once_cell",
+ "unicode-width 0.2.0",
+ "windows-sys",
]
[[package]]
name = "cpufeatures"
-version = "0.2.12"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-channel"
-version = "0.5.13"
+version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
+checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.20"
+version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crypto-common"
@@ -282,39 +282,39 @@
[[package]]
name = "directories"
-version = "5.0.1"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
name = "encode_unicode"
-version = "0.3.6"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
@@ -329,9 +329,9 @@
[[package]]
name = "fastrand"
-version = "2.1.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "generic-array"
@@ -356,14 +356,14 @@
[[package]]
name = "getrandom"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
- "wasi 0.13.3+wasi-0.2.2",
- "windows-targets 0.52.6",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
]
[[package]]
@@ -380,40 +380,41 @@
[[package]]
name = "indicatif"
-version = "0.17.8"
+version = "0.17.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
+checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
dependencies = [
"console",
- "instant",
"number_prefix",
"portable-atomic",
- "unicode-width",
+ "unicode-width 0.2.0",
+ "web-time",
]
[[package]]
name = "inout"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"generic-array",
]
[[package]]
-name = "instant"
-version = "0.1.13"
+name = "itoa"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
-dependencies = [
- "cfg-if",
-]
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
-name = "itoa"
-version = "1.0.11"
+name = "js-sys"
+version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
[[package]]
name = "lazy_static"
@@ -429,9 +430,9 @@
[[package]]
name = "libc"
-version = "0.2.155"
+version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libffi"
@@ -454,12 +455,12 @@
[[package]]
name = "libloading"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
+checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets",
]
[[package]]
@@ -474,9 +475,9 @@
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "lock_api"
@@ -490,15 +491,15 @@
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "measureme"
-version = "11.0.1"
+version = "12.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfa4a40f09af7aa6faef38285402a78847d0d72bf8827006cd2a332e1e6e4a8d"
+checksum = "570a507d8948a66a97f42cbbaf8a6bb9516a51017d4ee949502ad7a10a864395"
dependencies = [
"log",
"memmap2",
@@ -537,11 +538,12 @@
version = "0.1.0"
dependencies = [
"aes",
+ "bitflags",
"chrono",
"chrono-tz",
"colored",
"directories",
- "getrandom 0.3.1",
+ "getrandom 0.3.2",
"libc",
"libffi",
"libloading",
@@ -553,7 +555,7 @@
"tempfile",
"tikv-jemalloc-sys",
"ui_test",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
@@ -582,9 +584,9 @@
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "option-ext"
@@ -604,7 +606,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3"
dependencies = [
- "unicode-width",
+ "unicode-width 0.1.14",
]
[[package]]
@@ -627,7 +629,7 @@
"libc",
"redox_syscall",
"smallvec",
- "windows-targets 0.52.6",
+ "windows-targets",
]
[[package]]
@@ -650,18 +652,18 @@
[[package]]
name = "phf"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
"phf_generator",
"phf_shared",
@@ -669,9 +671,9 @@
[[package]]
name = "phf_generator"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
"rand 0.8.5",
@@ -679,32 +681,32 @@
[[package]]
name = "phf_shared"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
-version = "0.2.14"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "portable-atomic"
-version = "1.7.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "ppv-lite86"
-version = "0.2.20"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
- "zerocopy 0.7.35",
+ "zerocopy",
]
[[package]]
@@ -719,23 +721,29 @@
[[package]]
name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.36"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -751,8 +759,8 @@
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha",
- "rand_core 0.9.0",
- "zerocopy 0.8.14",
+ "rand_core 0.9.3",
+ "zerocopy",
]
[[package]]
@@ -762,7 +770,7 @@
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
- "rand_core 0.9.0",
+ "rand_core 0.9.3",
]
[[package]]
@@ -773,39 +781,38 @@
[[package]]
name = "rand_core"
-version = "0.9.0"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
- "getrandom 0.3.1",
- "zerocopy 0.8.14",
+ "getrandom 0.3.2",
]
[[package]]
name = "redox_syscall"
-version = "0.5.3"
+version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
+checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
-version = "0.4.5"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
+checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
"getrandom 0.2.15",
"libredox",
- "thiserror",
+ "thiserror 2.0.12",
]
[[package]]
name = "regex"
-version = "1.10.6"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@@ -815,9 +822,9 @@
[[package]]
name = "regex-automata"
-version = "0.4.7"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -826,9 +833,9 @@
[[package]]
name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-demangle"
@@ -844,43 +851,43 @@
[[package]]
name = "rustc_version"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustfix"
-version = "0.8.5"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70f5b7fc8060f4f8373f9381a630304b42e1183535d9beb1d3f596b236c9106a"
+checksum = "82fa69b198d894d84e23afde8e9ab2af4400b2cba20d6bf2b428a8b01c222c5a"
dependencies = [
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
]
[[package]]
name = "rustix"
-version = "0.38.34"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "scopeguard"
@@ -890,27 +897,27 @@
[[package]]
name = "semver"
-version = "1.0.23"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
dependencies = [
"serde",
]
[[package]]
name = "serde"
-version = "1.0.204"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.204"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -919,9 +926,9 @@
[[package]]
name = "serde_json"
-version = "1.0.122"
+version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
@@ -946,15 +953,15 @@
[[package]]
name = "siphasher"
-version = "0.3.11"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "smallvec"
-version = "1.13.2"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "spanned"
@@ -968,9 +975,9 @@
[[package]]
name = "syn"
-version = "2.0.72"
+version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@@ -979,31 +986,51 @@
[[package]]
name = "tempfile"
-version = "3.11.0"
+version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
- "cfg-if",
"fastrand",
+ "getrandom 0.3.2",
"once_cell",
"rustix",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "thiserror"
-version = "1.0.63"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "thiserror-impl",
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl 2.0.12",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.63"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
@@ -1032,9 +1059,9 @@
[[package]]
name = "tracing"
-version = "0.1.40"
+version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-core",
@@ -1042,9 +1069,9 @@
[[package]]
name = "tracing-core"
-version = "0.1.32"
+version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
"valuable",
@@ -1052,9 +1079,9 @@
[[package]]
name = "tracing-error"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
+checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
dependencies = [
"tracing",
"tracing-subscriber",
@@ -1062,9 +1089,9 @@
[[package]]
name = "tracing-subscriber"
-version = "0.3.18"
+version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
+checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"sharded-slab",
"thread_local",
@@ -1073,15 +1100,15 @@
[[package]]
name = "typenum"
-version = "1.17.0"
+version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "ui_test"
-version = "0.29.1"
+version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14bf63f2931a28a04af0bd24c5f850223d29f3a40afae49ed6ce442a65eb8652"
+checksum = "1211b1111c752c73b33073d2958072be08825fd97c9ab4d83444da361a06634b"
dependencies = [
"annotate-snippets",
"anyhow",
@@ -1105,21 +1132,27 @@
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unicode-width"
-version = "0.1.13"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
+[[package]]
+name = "unicode-width"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
name = "valuable"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "version_check"
@@ -1135,44 +1168,87 @@
[[package]]
name = "wasi"
-version = "0.13.3+wasi-0.2.2"
+version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
-name = "windows-sys"
-version = "0.48.0"
+name = "wasm-bindgen"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
- "windows-targets 0.48.5",
+ "cfg-if",
+ "once_cell",
+ "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"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "web-time"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
]
[[package]]
name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
]
[[package]]
@@ -1181,48 +1257,30 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
"windows_i686_gnullvm",
- "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_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[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_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
@@ -1235,96 +1293,51 @@
[[package]]
name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen-rt"
-version = "0.33.0"
+version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
-version = "0.7.35"
+version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
- "byteorder",
- "zerocopy-derive 0.7.35",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.8.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
-dependencies = [
- "zerocopy-derive 0.8.14",
+ "zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.35"
+version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 5d8c9a8..e9ee19b 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -22,10 +22,11 @@
rand = "0.9"
smallvec = { version = "1.7", features = ["drain_filter"] }
aes = { version = "0.8.3", features = ["hazmat"] }
-measureme = "11"
+measureme = "12"
chrono = { version = "0.4.38", default-features = false }
chrono-tz = "0.10"
-directories = "5"
+directories = "6"
+bitflags = "2.6"
# Copied from `compiler/rustc/Cargo.toml`.
# But only for some targets, it fails for others. Rustc configures this in its CI, but we can't
@@ -40,7 +41,7 @@
libloading = "0.8"
[target.'cfg(target_family = "windows")'.dependencies]
-windows-sys = { version = "0.52", features = [
+windows-sys = { version = "0.59", features = [
"Win32_Foundation",
"Win32_System_IO",
"Win32_Storage_FileSystem",
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 201aa1f..e8ea988 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -565,6 +565,7 @@
* [Occasional memory leak in `std::mpsc` channels](https://github.com/rust-lang/rust/issues/121582) (original code in [crossbeam](https://github.com/crossbeam-rs/crossbeam/pull/1084))
* [Weak-memory-induced memory leak in Windows thread-local storage](https://github.com/rust-lang/rust/pull/124281)
* [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo)
+* [Mockall reading unintialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite)
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
diff --git a/src/tools/miri/bench-cargo-miri/big-allocs/src/main.rs b/src/tools/miri/bench-cargo-miri/big-allocs/src/main.rs
index a1c1708..5b807ac 100644
--- a/src/tools/miri/bench-cargo-miri/big-allocs/src/main.rs
+++ b/src/tools/miri/bench-cargo-miri/big-allocs/src/main.rs
@@ -7,7 +7,10 @@ fn main() {
// We can't use too big of an allocation or this code will encounter an allocation failure in
// CI. Since the allocation can't be huge, we need to do a few iterations so that the effect
// we're trying to measure is clearly visible above the interpreter's startup time.
- for _ in 0..10 {
+ // FIXME (https://github.com/rust-lang/miri/issues/4253): On 32bit targets, we can run out of
+ // usable addresses if we don't reuse, leading to random test failures.
+ let count = if cfg!(target_pointer_width = "32") { 8 } else { 12 };
+ for _ in 0..count {
drop(Vec::<u8>::with_capacity(512 * 1024 * 1024));
}
}
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock
index b8e08d3..bd4ca28 100644
--- a/src/tools/miri/cargo-miri/Cargo.lock
+++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -4,21 +4,21 @@
[[package]]
name = "anyhow"
-version = "1.0.86"
+version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "camino"
-version = "1.1.7"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
+checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
dependencies = [
"serde",
]
@@ -38,18 +38,18 @@
[[package]]
name = "cargo-platform"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
dependencies = [
"serde",
]
[[package]]
name = "cargo_metadata"
-version = "0.18.1"
+version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
+checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
dependencies = [
"camino",
"cargo-platform",
@@ -67,40 +67,40 @@
[[package]]
name = "directories"
-version = "5.0.1"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "fastrand"
-version = "2.1.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "getrandom"
@@ -110,20 +110,32 @@
dependencies = [
"cfg-if",
"libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "itoa"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "libc"
-version = "0.2.155"
+version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libredox"
@@ -137,9 +149,9 @@
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "memchr"
@@ -149,9 +161,9 @@
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "option-ext"
@@ -161,29 +173,35 @@
[[package]]
name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.36"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
-name = "redox_users"
-version = "0.4.5"
+name = "r-efi"
+version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
+name = "redox_users"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
"libredox",
"thiserror",
]
@@ -202,37 +220,37 @@
[[package]]
name = "rustc_tools_util"
-version = "0.4.0"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3316159ab19e19d1065ecc49278e87f767a9dae9fae80348d2b4d4fa4ae02d4d"
+checksum = "a3b75158011a63889ba12084cf1224baad7bcad50f6ee7c842f772b74aa148ed"
[[package]]
name = "rustc_version"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
-version = "0.38.34"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
@@ -245,27 +263,27 @@
[[package]]
name = "semver"
-version = "1.0.23"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
dependencies = [
"serde",
]
[[package]]
name = "serde"
-version = "1.0.204"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.204"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -274,9 +292,9 @@
[[package]]
name = "serde_json"
-version = "1.0.122"
+version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
@@ -286,9 +304,9 @@
[[package]]
name = "syn"
-version = "2.0.72"
+version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@@ -297,31 +315,31 @@
[[package]]
name = "tempfile"
-version = "3.11.0"
+version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
- "cfg-if",
"fastrand",
+ "getrandom 0.3.2",
"once_cell",
"rustix",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "thiserror"
-version = "1.0.63"
+version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.63"
+version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
@@ -330,9 +348,9 @@
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "walkdir"
@@ -351,30 +369,21 @@
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
+ "windows-sys",
]
[[package]]
@@ -383,22 +392,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
]
[[package]]
@@ -407,48 +401,30 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
"windows_i686_gnullvm",
- "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_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[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_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
@@ -461,48 +437,33 @@
[[package]]
name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml
index de0988d..ed142b0 100644
--- a/src/tools/miri/cargo-miri/Cargo.toml
+++ b/src/tools/miri/cargo-miri/Cargo.toml
@@ -14,10 +14,10 @@
doctest = false # and no doc tests
[dependencies]
-directories = "5"
+directories = "6"
rustc_version = "0.4"
serde_json = "1.0.40"
-cargo_metadata = "0.18.0"
+cargo_metadata = "0.19"
rustc-build-sysroot = "0.5.4"
# Enable some feature flags that dev-dependencies need but dependencies
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 7155d69..b690bd9 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -164,7 +164,7 @@
# Partially supported targets (tier 2)
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
- TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
+ TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe concurrency sync
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync concurrency thread epoll eventfd
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
diff --git a/src/tools/miri/miri-script/Cargo.lock b/src/tools/miri/miri-script/Cargo.lock
index 25c6f81..3494a24 100644
--- a/src/tools/miri/miri-script/Cargo.lock
+++ b/src/tools/miri/miri-script/Cargo.lock
@@ -38,30 +38,31 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.6"
+version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
- "windows-sys 0.59.0",
+ "once_cell",
+ "windows-sys",
]
[[package]]
name = "anyhow"
-version = "1.0.80"
+version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "bitflags"
-version = "2.4.2"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "cfg-if"
@@ -71,9 +72,9 @@
[[package]]
name = "clap"
-version = "4.5.23"
+version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
+checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944"
dependencies = [
"clap_builder",
"clap_derive",
@@ -81,9 +82,9 @@
[[package]]
name = "clap_builder"
-version = "4.5.23"
+version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
+checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9"
dependencies = [
"anstream",
"anstyle",
@@ -93,9 +94,9 @@
[[package]]
name = "clap_derive"
-version = "4.5.18"
+version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
@@ -117,62 +118,80 @@
[[package]]
name = "directories"
-version = "5.0.1"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
name = "dunce"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
name = "either"
-version = "1.10.0"
+version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "env_home"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
name = "fastrand"
-version = "2.1.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "getrandom"
-version = "0.2.12"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
]
[[package]]
@@ -182,15 +201,6 @@
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
-name = "home"
-version = "0.5.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -198,24 +208,24 @@
[[package]]
name = "itertools"
-version = "0.11.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "libc"
-version = "0.2.159"
+version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libredox"
@@ -229,9 +239,15 @@
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "memchr"
@@ -262,9 +278,9 @@
[[package]]
name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "option-ext"
@@ -280,60 +296,79 @@
[[package]]
name = "proc-macro2"
-version = "1.0.78"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.35"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
-name = "redox_users"
-version = "0.4.6"
+name = "r-efi"
+version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
+name = "redox_users"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
"libredox",
"thiserror",
]
[[package]]
name = "rustc_version"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
-version = "0.38.37"
+version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"errno",
"libc",
- "linux-raw-sys",
- "windows-sys 0.52.0",
+ "linux-raw-sys 0.4.15",
+ "windows-sys",
+]
+
+[[package]]
+name = "rustix"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.9.3",
+ "windows-sys",
]
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
@@ -346,24 +381,24 @@
[[package]]
name = "semver"
-version = "1.0.22"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
+checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
[[package]]
name = "serde"
-version = "1.0.210"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.210"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -372,9 +407,9 @@
[[package]]
name = "serde_json"
-version = "1.0.128"
+version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
@@ -396,9 +431,9 @@
[[package]]
name = "syn"
-version = "2.0.50"
+version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@@ -407,31 +442,31 @@
[[package]]
name = "tempfile"
-version = "3.13.0"
+version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
- "cfg-if",
"fastrand",
+ "getrandom 0.3.2",
"once_cell",
- "rustix",
- "windows-sys 0.59.0",
+ "rustix 1.0.5",
+ "windows-sys",
]
[[package]]
name = "thiserror"
-version = "1.0.57"
+version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.57"
+version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
@@ -440,9 +475,9 @@
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
@@ -452,9 +487,9 @@
[[package]]
name = "walkdir"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
@@ -467,14 +502,23 @@
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
-name = "which"
-version = "6.0.3"
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
+name = "which"
+version = "7.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2774c861e1f072b3aadc02f8ba886c26ad6321567ecc294c935434cad06f1283"
dependencies = [
"either",
- "home",
- "rustix",
+ "env_home",
+ "rustix 0.38.44",
"winsafe",
]
@@ -484,25 +528,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
+ "windows-sys",
]
[[package]]
@@ -511,22 +537,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
]
[[package]]
@@ -535,48 +546,30 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
"windows_i686_gnullvm",
- "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_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[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_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
@@ -589,48 +582,24 @@
[[package]]
name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
@@ -642,6 +611,15 @@
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "xshell"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/miri/miri-script/Cargo.toml b/src/tools/miri/miri-script/Cargo.toml
index 5879b27..a04898d 100644
--- a/src/tools/miri/miri-script/Cargo.toml
+++ b/src/tools/miri/miri-script/Cargo.toml
@@ -13,16 +13,16 @@
# This is needed to make this package build on stable when the parent package uses unstable cargo features.
[dependencies]
-which = "6.0"
+which = "7"
walkdir = "2.3"
-itertools = "0.11"
+itertools = "0.14"
path_macro = "1.0"
shell-words = "1.1"
anyhow = "1.0"
xshell = "0.2.6"
rustc_version = "0.4"
dunce = "1.0.4"
-directories = "5"
+directories = "6"
serde = "1"
serde_json = "1"
serde_derive = "1"
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index cf36b6f..d2b8b51 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-4ac032f857b46037b55c1fc0fa702450aad37f43
+7d7de5bf3c3cbf9c2c5bbc5cbfb9197a8a427d35
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 56ee965..4e8fe0c 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -185,7 +185,7 @@ fn after_analysis<'tcx>(
let num_failed = sync::IntoDynSyncSend(AtomicU32::new(0));
sync::par_for_each_in(many_seeds.seeds.clone(), |seed| {
let mut config = config.clone();
- config.seed = Some(seed.into());
+ config.seed = Some((*seed).into());
eprintln!("Trying seed: {seed}");
let return_code = miri::eval_entry(tcx, entry_def_id, entry_type, config)
.unwrap_or(rustc_driver::EXIT_FAILURE);
diff --git a/src/tools/miri/src/clock.rs b/src/tools/miri/src/clock.rs
index c9bffc4..34465e9 100644
--- a/src/tools/miri/src/clock.rs
+++ b/src/tools/miri/src/clock.rs
@@ -62,12 +62,12 @@ pub fn duration_since(&self, earlier: Instant) -> Duration {
/// A monotone clock used for `Instant` simulation.
#[derive(Debug)]
-pub struct Clock {
- kind: ClockKind,
+pub struct MonotonicClock {
+ kind: MonotonicClockKind,
}
#[derive(Debug)]
-enum ClockKind {
+enum MonotonicClockKind {
Host {
/// The "epoch" for this machine's monotone clock:
/// the moment we consider to be time = 0.
@@ -79,13 +79,13 @@ enum ClockKind {
},
}
-impl Clock {
+impl MonotonicClock {
/// Create a new clock based on the availability of communication with the host.
pub fn new(communicate: bool) -> Self {
let kind = if communicate {
- ClockKind::Host { epoch: StdInstant::now() }
+ MonotonicClockKind::Host { epoch: StdInstant::now() }
} else {
- ClockKind::Virtual { nanoseconds: 0.into() }
+ MonotonicClockKind::Virtual { nanoseconds: 0.into() }
};
Self { kind }
@@ -94,10 +94,10 @@ pub fn new(communicate: bool) -> Self {
/// Let the time pass for a small interval.
pub fn tick(&self) {
match &self.kind {
- ClockKind::Host { .. } => {
+ MonotonicClockKind::Host { .. } => {
// Time will pass without us doing anything.
}
- ClockKind::Virtual { nanoseconds } => {
+ MonotonicClockKind::Virtual { nanoseconds } => {
nanoseconds.update(|x| x + NANOSECONDS_PER_BASIC_BLOCK);
}
}
@@ -106,8 +106,8 @@ pub fn tick(&self) {
/// Sleep for the desired duration.
pub fn sleep(&self, duration: Duration) {
match &self.kind {
- ClockKind::Host { .. } => std::thread::sleep(duration),
- ClockKind::Virtual { nanoseconds } => {
+ MonotonicClockKind::Host { .. } => std::thread::sleep(duration),
+ MonotonicClockKind::Virtual { nanoseconds } => {
// Just pretend that we have slept for some time.
let nanos: u128 = duration.as_nanos();
nanoseconds.update(|x| {
@@ -121,15 +121,17 @@ pub fn sleep(&self, duration: Duration) {
/// Return the `epoch` instant (time = 0), to convert between monotone instants and absolute durations.
pub fn epoch(&self) -> Instant {
match &self.kind {
- ClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
- ClockKind::Virtual { .. } => Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
+ MonotonicClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
+ MonotonicClockKind::Virtual { .. } =>
+ Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
}
}
pub fn now(&self) -> Instant {
match &self.kind {
- ClockKind::Host { .. } => Instant { kind: InstantKind::Host(StdInstant::now()) },
- ClockKind::Virtual { nanoseconds } =>
+ MonotonicClockKind::Host { .. } =>
+ Instant { kind: InstantKind::Host(StdInstant::now()) },
+ MonotonicClockKind::Virtual { nanoseconds } =>
Instant { kind: InstantKind::Virtual { nanoseconds: nanoseconds.get() } },
}
}
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 9462996..72fa918 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -347,7 +347,7 @@ enum Timeout {
impl Timeout {
/// How long do we have to wait from now until the specified time?
- fn get_wait_time(&self, clock: &Clock) -> Duration {
+ fn get_wait_time(&self, clock: &MonotonicClock) -> Duration {
match self {
Timeout::Monotonic(instant) => instant.duration_since(clock.now()),
Timeout::RealTime(time) =>
@@ -683,7 +683,7 @@ fn yield_active_thread(&mut self) {
}
/// Get the wait time for the next timeout, or `None` if no timeout is pending.
- fn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration> {
+ fn next_callback_wait_time(&self, clock: &MonotonicClock) -> Option<Duration> {
self.threads
.iter()
.filter_map(|t| {
@@ -702,7 +702,7 @@ fn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration> {
/// used in stateless model checkers such as Loom: run the active thread as
/// long as we can and switch only when we have to (the active thread was
/// blocked, terminated, or has explicitly asked to be preempted).
- fn schedule(&mut self, clock: &Clock) -> InterpResult<'tcx, SchedulingAction> {
+ fn schedule(&mut self, clock: &MonotonicClock) -> InterpResult<'tcx, SchedulingAction> {
// This thread and the program can keep going.
if self.threads[self.active_thread].state.is_enabled() && !self.yield_active_thread {
// The currently active thread is still enabled, just continue with it.
@@ -772,7 +772,7 @@ fn run_timeout_callback(&mut self) -> InterpResult<'tcx> {
for (id, thread) in this.machine.threads.threads.iter_enumerated_mut() {
match &thread.state {
ThreadState::Blocked { timeout: Some(timeout), .. }
- if timeout.get_wait_time(&this.machine.clock) == Duration::ZERO =>
+ if timeout.get_wait_time(&this.machine.monotonic_clock) == Duration::ZERO =>
{
let old_state = mem::replace(&mut thread.state, ThreadState::Enabled);
let ThreadState::Blocked { callback, .. } = old_state else { unreachable!() };
@@ -1006,8 +1006,8 @@ fn block_thread(
}
TimeoutClock::Monotonic =>
Timeout::Monotonic(match anchor {
- TimeoutAnchor::Absolute => this.machine.clock.epoch(),
- TimeoutAnchor::Relative => this.machine.clock.now(),
+ TimeoutAnchor::Absolute => this.machine.monotonic_clock.epoch(),
+ TimeoutAnchor::Relative => this.machine.monotonic_clock.now(),
}),
};
anchor.add_lossy(duration)
@@ -1152,7 +1152,7 @@ fn run_threads(&mut self) -> InterpResult<'tcx, !> {
this.machine.handle_abnormal_termination();
throw_machine_stop!(TerminationInfo::Interrupted);
}
- match this.machine.threads.schedule(&this.machine.clock)? {
+ match this.machine.threads.schedule(&this.machine.monotonic_clock)? {
SchedulingAction::ExecuteStep => {
if !this.step()? {
// See if this thread can do something else.
@@ -1167,7 +1167,7 @@ fn run_threads(&mut self) -> InterpResult<'tcx, !> {
this.run_timeout_callback()?;
}
SchedulingAction::Sleep(duration) => {
- this.machine.clock.sleep(duration);
+ this.machine.monotonic_clock.sleep(duration);
}
}
}
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index ed13f67..7586b5e 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -459,8 +459,13 @@ pub fn eval_entry<'tcx>(
ecx.handle_ice();
panic::resume_unwind(panic_payload)
});
- // `Ok` can never happen.
+ // `Ok` can never happen; the interpreter loop always exits with an "error"
+ // (but that "error" might be just "regular program termination").
let Err(err) = res.report_err();
+ // Show diagnostic, if any.
+ let (return_code, leak_check) = report_error(&ecx, err)?;
+
+ // If we get here there was no fatal error.
// Machine cleanup. Only do this if all threads have terminated; threads that are still running
// might cause Stacked Borrows errors (https://github.com/rust-lang/miri/issues/2396).
@@ -472,8 +477,7 @@ pub fn eval_entry<'tcx>(
EnvVars::cleanup(&mut ecx).expect("error during env var cleanup");
}
- // Process the result.
- let (return_code, leak_check) = report_error(&ecx, err)?;
+ // Possibly check for memory leaks.
if leak_check && !ignore_leaks {
// Check for thread leaks.
if !ecx.have_all_terminated() {
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 29ed94a..b4098ca 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -602,6 +602,9 @@ fn visit_value(&mut self, v: &MPlaceTy<'tcx>) -> InterpResult<'tcx> {
// We want to not actually read from memory for this visit. So, before
// walking this value, we have to make sure it is not a
// `Variants::Multiple`.
+ // FIXME: the current logic here is layout-dependent, so enums with
+ // multiple variants where all but 1 are uninhabited will be recursed into.
+ // Is that truly what we want?
match v.layout.variants {
Variants::Multiple { .. } => {
// A multi-variant enum, or coroutine, or so.
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 03f76cf..5921ba8 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -121,7 +121,7 @@
};
pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree};
pub use crate::borrow_tracker::{BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields};
-pub use crate::clock::{Clock, Instant};
+pub use crate::clock::{Instant, MonotonicClock};
pub use crate::concurrency::cpu_affinity::MAX_CPUS;
pub use crate::concurrency::data_race::{
AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, EvalContextExt as _,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index fb99bdc..ea59d32 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -486,7 +486,7 @@ pub struct MiriMachine<'tcx> {
pub(crate) epoll_interests: shims::EpollInterestTable,
/// This machine's monotone clock.
- pub(crate) clock: Clock,
+ pub(crate) monotonic_clock: MonotonicClock,
/// The set of threads.
pub(crate) threads: ThreadManager<'tcx>,
@@ -713,7 +713,7 @@ pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx>) -> Self {
preemption_rate: config.preemption_rate,
report_progress: config.report_progress,
basic_block_count: 0,
- clock: Clock::new(config.isolated_op == IsolatedOp::Allow),
+ monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow),
#[cfg(unix)]
native_lib: config.native_lib.as_ref().map(|lib_file_path| {
let host_triple = rustc_session::config::host_tuple();
@@ -896,7 +896,7 @@ fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
tcx: _,
isolated_op: _,
validation: _,
- clock: _,
+ monotonic_clock: _,
layouts: _,
static_roots: _,
profiler: _,
@@ -1568,7 +1568,7 @@ fn before_terminator(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
ecx.maybe_preempt_active_thread();
// Make sure some time passes.
- ecx.machine.clock.tick();
+ ecx.machine.monotonic_clock.tick();
interp_ok(())
}
diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs
index 6b4f4cd..42603e7 100644
--- a/src/tools/miri/src/shims/files.rs
+++ b/src/tools/miri/src/shims/files.rs
@@ -1,6 +1,7 @@
use std::any::Any;
use std::collections::BTreeMap;
-use std::io::{IsTerminal, SeekFrom, Write};
+use std::fs::{File, Metadata};
+use std::io::{IsTerminal, Seek, SeekFrom, Write};
use std::marker::CoercePointee;
use std::ops::Deref;
use std::rc::{Rc, Weak};
@@ -192,7 +193,7 @@ fn is_tty(&self, _communicate_allowed: bool) -> bool {
false
}
- fn as_unix(&self) -> &dyn UnixFileDescription {
+ fn as_unix<'tcx>(&self, _ecx: &MiriInterpCx<'tcx>) -> &dyn UnixFileDescription {
panic!("Not a unix file descriptor: {}", self.name());
}
}
@@ -278,6 +279,97 @@ fn is_tty(&self, communicate_allowed: bool) -> bool {
}
}
+#[derive(Debug)]
+pub struct FileHandle {
+ pub(crate) file: File,
+ pub(crate) writable: bool,
+}
+
+impl FileDescription for FileHandle {
+ fn name(&self) -> &'static str {
+ "file"
+ }
+
+ fn read<'tcx>(
+ self: FileDescriptionRef<Self>,
+ communicate_allowed: bool,
+ ptr: Pointer,
+ len: usize,
+ ecx: &mut MiriInterpCx<'tcx>,
+ finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
+ ) -> InterpResult<'tcx> {
+ assert!(communicate_allowed, "isolation should have prevented even opening a file");
+
+ let result = ecx.read_from_host(&self.file, len, ptr)?;
+ finish.call(ecx, result)
+ }
+
+ fn write<'tcx>(
+ self: FileDescriptionRef<Self>,
+ communicate_allowed: bool,
+ ptr: Pointer,
+ len: usize,
+ ecx: &mut MiriInterpCx<'tcx>,
+ finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
+ ) -> InterpResult<'tcx> {
+ assert!(communicate_allowed, "isolation should have prevented even opening a file");
+
+ let result = ecx.write_to_host(&self.file, len, ptr)?;
+ finish.call(ecx, result)
+ }
+
+ fn seek<'tcx>(
+ &self,
+ communicate_allowed: bool,
+ offset: SeekFrom,
+ ) -> InterpResult<'tcx, io::Result<u64>> {
+ assert!(communicate_allowed, "isolation should have prevented even opening a file");
+ interp_ok((&mut &self.file).seek(offset))
+ }
+
+ fn close<'tcx>(
+ self,
+ communicate_allowed: bool,
+ _ecx: &mut MiriInterpCx<'tcx>,
+ ) -> InterpResult<'tcx, io::Result<()>> {
+ assert!(communicate_allowed, "isolation should have prevented even opening a file");
+ // We sync the file if it was opened in a mode different than read-only.
+ if self.writable {
+ // `File::sync_all` does the checks that are done when closing a file. We do this to
+ // to handle possible errors correctly.
+ let result = self.file.sync_all();
+ // Now we actually close the file and return the result.
+ drop(self.file);
+ interp_ok(result)
+ } else {
+ // We drop the file, this closes it but ignores any errors
+ // produced when closing it. This is done because
+ // `File::sync_all` cannot be done over files like
+ // `/dev/urandom` which are read-only. Check
+ // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439
+ // for a deeper discussion.
+ drop(self.file);
+ interp_ok(Ok(()))
+ }
+ }
+
+ fn metadata<'tcx>(&self) -> InterpResult<'tcx, io::Result<Metadata>> {
+ interp_ok(self.file.metadata())
+ }
+
+ fn is_tty(&self, communicate_allowed: bool) -> bool {
+ communicate_allowed && self.file.is_terminal()
+ }
+
+ fn as_unix<'tcx>(&self, ecx: &MiriInterpCx<'tcx>) -> &dyn UnixFileDescription {
+ assert!(
+ ecx.target_os_is_unix(),
+ "unix file operations are only available for unix targets"
+ );
+ self
+ }
+}
+
/// Like /dev/null
#[derive(Debug)]
pub struct NullOutput;
@@ -300,10 +392,13 @@ fn write<'tcx>(
}
}
+/// Internal type of a file-descriptor - this is what [`FdTable`] expects
+pub type FdNum = i32;
+
/// The file descriptor table
#[derive(Debug)]
pub struct FdTable {
- pub fds: BTreeMap<i32, DynFileDescriptionRef>,
+ pub fds: BTreeMap<FdNum, DynFileDescriptionRef>,
/// Unique identifier for file description, used to differentiate between various file description.
next_file_description_id: FdId,
}
@@ -339,12 +434,12 @@ pub fn new_ref<T: FileDescription>(&mut self, fd: T) -> FileDescriptionRef<T> {
}
/// Insert a new file description to the FdTable.
- pub fn insert_new(&mut self, fd: impl FileDescription) -> i32 {
+ pub fn insert_new(&mut self, fd: impl FileDescription) -> FdNum {
let fd_ref = self.new_ref(fd);
self.insert(fd_ref)
}
- pub fn insert(&mut self, fd_ref: DynFileDescriptionRef) -> i32 {
+ pub fn insert(&mut self, fd_ref: DynFileDescriptionRef) -> FdNum {
self.insert_with_min_num(fd_ref, 0)
}
@@ -352,8 +447,8 @@ pub fn insert(&mut self, fd_ref: DynFileDescriptionRef) -> i32 {
pub fn insert_with_min_num(
&mut self,
file_handle: DynFileDescriptionRef,
- min_fd_num: i32,
- ) -> i32 {
+ min_fd_num: FdNum,
+ ) -> FdNum {
// Find the lowest unused FD, starting from min_fd. If the first such unused FD is in
// between used FDs, the find_map combinator will return it. If the first such unused FD
// is after all other used FDs, the find_map combinator will return None, and we will use
@@ -379,16 +474,16 @@ pub fn insert_with_min_num(
new_fd_num
}
- pub fn get(&self, fd_num: i32) -> Option<DynFileDescriptionRef> {
+ pub fn get(&self, fd_num: FdNum) -> Option<DynFileDescriptionRef> {
let fd = self.fds.get(&fd_num)?;
Some(fd.clone())
}
- pub fn remove(&mut self, fd_num: i32) -> Option<DynFileDescriptionRef> {
+ pub fn remove(&mut self, fd_num: FdNum) -> Option<DynFileDescriptionRef> {
self.fds.remove(&fd_num)
}
- pub fn is_fd_num(&self, fd_num: i32) -> bool {
+ pub fn is_fd_num(&self, fd_num: FdNum) -> bool {
self.fds.contains_key(&fd_num)
}
}
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 64b3ce6..fb80a36 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -79,7 +79,7 @@ fn clock_gettime(
this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
system_time_to_duration(&SystemTime::now())?
} else if relative_clocks.contains(&clk_id) {
- this.machine.clock.now().duration_since(this.machine.clock.epoch())
+ this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch())
} else {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};
@@ -219,16 +219,8 @@ fn GetSystemTimeAsFileTime(
let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
- let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
- let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
- let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH");
- let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
- let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;
-
- let duration = system_time_to_duration(&SystemTime::now())?
- + Duration::from_secs(SECONDS_TO_UNIX_EPOCH);
- let duration_ticks = u64::try_from(duration.as_nanos() / u128::from(NANOS_PER_INTERVAL))
- .map_err(|_| err_unsup_format!("programs running more than 2^64 Windows ticks after the Windows epoch are not supported"))?;
+ let duration = this.system_time_since_windows_epoch(&SystemTime::now())?;
+ let duration_ticks = this.windows_ticks_for(duration)?;
let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap();
let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap();
@@ -248,7 +240,8 @@ fn QueryPerformanceCounter(
// QueryPerformanceCounter uses a hardware counter as its basis.
// Miri will emulate a counter with a resolution of 1 nanosecond.
- let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
+ let duration =
+ this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
})?;
@@ -280,6 +273,30 @@ fn QueryPerformanceFrequency(
interp_ok(Scalar::from_i32(-1)) // Return non-zero on success
}
+ #[allow(non_snake_case, clippy::arithmetic_side_effects)]
+ fn system_time_since_windows_epoch(&self, time: &SystemTime) -> InterpResult<'tcx, Duration> {
+ let this = self.eval_context_ref();
+
+ let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
+ let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH");
+ let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;
+
+ interp_ok(system_time_to_duration(time)? + Duration::from_secs(SECONDS_TO_UNIX_EPOCH))
+ }
+
+ #[allow(non_snake_case, clippy::arithmetic_side_effects)]
+ fn windows_ticks_for(&self, duration: Duration) -> InterpResult<'tcx, u64> {
+ let this = self.eval_context_ref();
+
+ let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
+ let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
+ let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
+
+ let ticks = u64::try_from(duration.as_nanos() / u128::from(NANOS_PER_INTERVAL))
+ .map_err(|_| err_unsup_format!("programs running more than 2^64 Windows ticks after the Windows epoch are not supported"))?;
+ interp_ok(ticks)
+ }
+
fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_ref();
@@ -287,7 +304,8 @@ fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar> {
// This returns a u64, with time units determined dynamically by `mach_timebase_info`.
// We return plain nanoseconds.
- let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
+ let duration =
+ this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
let res = u64::try_from(duration.as_nanos()).map_err(|_| {
err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported")
})?;
diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs
index 3f85b9a..41be9df 100644
--- a/src/tools/miri/src/shims/unix/fd.rs
+++ b/src/tools/miri/src/shims/unix/fd.rs
@@ -121,7 +121,7 @@ fn flock(&mut self, fd_num: i32, op: i32) -> InterpResult<'tcx, Scalar> {
throw_unsup_format!("unsupported flags {:#x}", op);
};
- let result = fd.as_unix().flock(this.machine.communicate(), parsed_op)?;
+ let result = fd.as_unix(this).flock(this.machine.communicate(), parsed_op)?;
// return `0` if flock is successful
let result = result.map(|()| 0i32);
interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
@@ -273,7 +273,7 @@ fn read(
let Ok(offset) = u64::try_from(offset) else {
return this.set_last_error_and_return(LibcError("EINVAL"), dest);
};
- fd.as_unix().pread(communicate, offset, buf, count, this, finish)?
+ fd.as_unix(this).pread(communicate, offset, buf, count, this, finish)?
}
};
interp_ok(())
@@ -333,7 +333,7 @@ fn write(
let Ok(offset) = u64::try_from(offset) else {
return this.set_last_error_and_return(LibcError("EINVAL"), dest);
};
- fd.as_unix().pwrite(communicate, buf, count, offset, this, finish)?
+ fd.as_unix(this).pwrite(communicate, buf, count, offset, this, finish)?
}
};
interp_ok(())
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 1770b99..5e6259c 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -231,6 +231,8 @@ fn emulate_foreign_item_inner(
this.write_scalar(result, dest)?;
}
"flock" => {
+ // Currently this function does not exist on all Unixes, e.g. on Solaris.
+ this.check_target_os(&["linux", "freebsd", "macos", "illumos"], link_name)?;
let [fd, op] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let op = this.read_scalar(op)?.to_i32()?;
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 08d06fe..21a386b 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -2,6 +2,7 @@
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};
+use super::sync::EvalContextExt as _;
use crate::shims::unix::*;
use crate::*;
@@ -55,6 +56,13 @@ fn emulate_foreign_item_inner(
this.write_scalar(res, dest)?;
}
+ // Synchronization primitives
+ "_umtx_op" => {
+ let [obj, op, val, uaddr, uaddr2] =
+ this.check_shim(abi, Conv::C, link_name, args)?;
+ this._umtx_op(obj, op, val, uaddr, uaddr2, dest)?;
+ }
+
// File related shims
// For those, we both intercept `func` and `call@FBSD_1.0` symbols cases
// since freebsd 12 the former form can be expected.
diff --git a/src/tools/miri/src/shims/unix/freebsd/mod.rs b/src/tools/miri/src/shims/unix/freebsd/mod.rs
index 09c6507..50fb2b9 100644
--- a/src/tools/miri/src/shims/unix/freebsd/mod.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/mod.rs
@@ -1 +1,2 @@
pub mod foreign_items;
+pub mod sync;
diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs
new file mode 100644
index 0000000..54650f3
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs
@@ -0,0 +1,251 @@
+//! Contains FreeBSD-specific synchronization functions
+
+use core::time::Duration;
+
+use crate::concurrency::sync::FutexRef;
+use crate::*;
+
+pub struct FreeBsdFutex {
+ futex: FutexRef,
+}
+
+/// Extended variant of the `timespec` struct.
+pub struct UmtxTime {
+ timeout: Duration,
+ abs_time: bool,
+ timeout_clock: TimeoutClock,
+}
+
+impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
+pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+ /// Implementation of the FreeBSD [`_umtx_op`](https://man.freebsd.org/cgi/man.cgi?query=_umtx_op&sektion=2&manpath=FreeBSD+14.2-RELEASE+and+Ports) syscall.
+ /// This is used for futex operations on FreeBSD.
+ ///
+ /// `obj`: a pointer to the futex object (can be a lot of things, mostly *AtomicU32)
+ /// `op`: the futex operation to run
+ /// `val`: the current value of the object as a `c_long` (for wait/wake)
+ /// `uaddr`: `op`-specific optional parameter, pointer-sized integer or pointer to an `op`-specific struct
+ /// `uaddr2`: `op`-specific optional parameter, pointer-sized integer or pointer to an `op`-specific struct
+ /// `dest`: the place this syscall returns to, 0 for success, -1 for failure
+ ///
+ /// # Note
+ /// Curently only the WAIT and WAKE operations are implemented.
+ fn _umtx_op(
+ &mut self,
+ obj: &OpTy<'tcx>,
+ op: &OpTy<'tcx>,
+ val: &OpTy<'tcx>,
+ uaddr: &OpTy<'tcx>,
+ uaddr2: &OpTy<'tcx>,
+ dest: &MPlaceTy<'tcx>,
+ ) -> InterpResult<'tcx> {
+ let this = self.eval_context_mut();
+
+ let obj = this.read_pointer(obj)?;
+ let op = this.read_scalar(op)?.to_i32()?;
+ let val = this.read_target_usize(val)?;
+ let uaddr = this.read_target_usize(uaddr)?;
+ let uaddr2 = this.read_pointer(uaddr2)?;
+
+ let wait = this.eval_libc_i32("UMTX_OP_WAIT");
+ let wait_uint = this.eval_libc_i32("UMTX_OP_WAIT_UINT");
+ let wait_uint_private = this.eval_libc_i32("UMTX_OP_WAIT_UINT_PRIVATE");
+
+ let wake = this.eval_libc_i32("UMTX_OP_WAKE");
+ let wake_private = this.eval_libc_i32("UMTX_OP_WAKE_PRIVATE");
+
+ let timespec_layout = this.libc_ty_layout("timespec");
+ let umtx_time_layout = this.libc_ty_layout("_umtx_time");
+ assert!(
+ timespec_layout.size != umtx_time_layout.size,
+ "`struct timespec` and `struct _umtx_time` should have different sizes."
+ );
+
+ match op {
+ // UMTX_OP_WAIT_UINT and UMTX_OP_WAIT_UINT_PRIVATE only differ in whether they work across
+ // processes or not. For Miri, we can treat them the same.
+ op if op == wait || op == wait_uint || op == wait_uint_private => {
+ let obj_layout =
+ if op == wait { this.machine.layouts.isize } else { this.machine.layouts.u32 };
+ let obj = this.ptr_to_mplace(obj, obj_layout);
+
+ // Read the Linux futex wait implementation in Miri to understand why this fence is needed.
+ this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+ let obj_val = this
+ .read_scalar_atomic(&obj, AtomicReadOrd::Acquire)?
+ .to_bits(obj_layout.size)?; // isize and u32 can have different sizes
+
+ if obj_val == u128::from(val) {
+ // This cannot fail since we already did an atomic acquire read on that pointer.
+ // Acquire reads are only allowed on mutable memory.
+ let futex_ref = this
+ .get_sync_or_init(obj.ptr(), |_| FreeBsdFutex { futex: Default::default() })
+ .unwrap()
+ .futex
+ .clone();
+
+ // From the manual:
+ // The timeout is specified by passing either the address of `struct timespec`, or its
+ // extended variant, `struct _umtx_time`, as the `uaddr2` argument of _umtx_op().
+ // They are distinguished by the `uaddr` value, which must be equal
+ // to the size of the structure pointed to by `uaddr2`, casted to uintptr_t.
+ let timeout = if this.ptr_is_null(uaddr2)? {
+ // no timeout parameter
+ None
+ } else {
+ if uaddr == umtx_time_layout.size.bytes() {
+ // `uaddr2` points to a `struct _umtx_time`.
+ let umtx_time_place = this.ptr_to_mplace(uaddr2, umtx_time_layout);
+
+ let umtx_time = match this.read_umtx_time(&umtx_time_place)? {
+ Some(ut) => ut,
+ None => {
+ return this
+ .set_last_error_and_return(LibcError("EINVAL"), dest);
+ }
+ };
+
+ let anchor = if umtx_time.abs_time {
+ TimeoutAnchor::Absolute
+ } else {
+ TimeoutAnchor::Relative
+ };
+
+ Some((umtx_time.timeout_clock, anchor, umtx_time.timeout))
+ } else if uaddr == timespec_layout.size.bytes() {
+ // RealTime clock can't be used in isolation mode.
+ this.check_no_isolation("`_umtx_op` with `timespec` timeout")?;
+
+ // `uaddr2` points to a `struct timespec`.
+ let timespec = this.ptr_to_mplace(uaddr2, timespec_layout);
+ let duration = match this.read_timespec(×pec)? {
+ Some(duration) => duration,
+ None => {
+ return this
+ .set_last_error_and_return(LibcError("EINVAL"), dest);
+ }
+ };
+
+ // FreeBSD does not seem to document which clock is used when the timeout
+ // is passed as a `struct timespec*`. Based on discussions online and the source
+ // code (umtx_copyin_umtx_time() in kern_umtx.c), it seems to default to CLOCK_REALTIME,
+ // so that's what we also do.
+ // Discussion in golang: https://github.com/golang/go/issues/17168#issuecomment-250235271
+ Some((TimeoutClock::RealTime, TimeoutAnchor::Relative, duration))
+ } else {
+ return this.set_last_error_and_return(LibcError("EINVAL"), dest);
+ }
+ };
+
+ let dest = dest.clone();
+ this.futex_wait(
+ futex_ref,
+ u32::MAX, // we set the bitset to include all bits
+ timeout,
+ callback!(
+ @capture<'tcx> {
+ dest: MPlaceTy<'tcx>,
+ }
+ |ecx, unblock: UnblockKind| match unblock {
+ UnblockKind::Ready => {
+ // From the manual:
+ // If successful, all requests, except UMTX_SHM_CREAT and UMTX_SHM_LOOKUP
+ // sub-requests of the UMTX_OP_SHM request, will return zero.
+ ecx.write_int(0, &dest)
+ }
+ UnblockKind::TimedOut => {
+ ecx.set_last_error_and_return(LibcError("ETIMEDOUT"), &dest)
+ }
+ }
+ ),
+ );
+ interp_ok(())
+ } else {
+ // The manual doesn’t specify what should happen if the futex value doesn’t match the expected one.
+ // On FreeBSD 14.2, testing shows that WAIT operations return 0 even when the value is incorrect.
+ this.write_int(0, dest)?;
+ interp_ok(())
+ }
+ }
+ // UMTX_OP_WAKE and UMTX_OP_WAKE_PRIVATE only differ in whether they work across
+ // processes or not. For Miri, we can treat them the same.
+ op if op == wake || op == wake_private => {
+ let Some(futex_ref) =
+ this.get_sync_or_init(obj, |_| FreeBsdFutex { futex: Default::default() })
+ else {
+ // From Linux implemenation:
+ // No AllocId, or no live allocation at that AllocId.
+ // Return an error code. (That seems nicer than silently doing something non-intuitive.)
+ // This means that if an address gets reused by a new allocation,
+ // we'll use an independent futex queue for this... that seems acceptable.
+ return this.set_last_error_and_return(LibcError("EFAULT"), dest);
+ };
+ let futex_ref = futex_ref.futex.clone();
+
+ // Saturating cast for when usize is smaller than u64.
+ let count = usize::try_from(val).unwrap_or(usize::MAX);
+
+ // Read the Linux futex wake implementation in Miri to understand why this fence is needed.
+ this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+
+ // `_umtx_op` doesn't return the amount of woken threads.
+ let _woken = this.futex_wake(
+ &futex_ref,
+ u32::MAX, // we set the bitset to include all bits
+ count,
+ )?;
+
+ // From the manual:
+ // If successful, all requests, except UMTX_SHM_CREAT and UMTX_SHM_LOOKUP
+ // sub-requests of the UMTX_OP_SHM request, will return zero.
+ this.write_int(0, dest)?;
+ interp_ok(())
+ }
+ op => {
+ throw_unsup_format!("Miri does not support `_umtx_op` syscall with op={}", op)
+ }
+ }
+ }
+
+ /// Parses a `_umtx_time` struct.
+ /// Returns `None` if the underlying `timespec` struct is invalid.
+ fn read_umtx_time(&mut self, ut: &MPlaceTy<'tcx>) -> InterpResult<'tcx, Option<UmtxTime>> {
+ let this = self.eval_context_mut();
+ // Only flag allowed is UMTX_ABSTIME.
+ let abs_time = this.eval_libc_u32("UMTX_ABSTIME");
+
+ let timespec_place = this.project_field(ut, 0)?;
+ // Inner `timespec` must still be valid.
+ let duration = match this.read_timespec(×pec_place)? {
+ Some(dur) => dur,
+ None => return interp_ok(None),
+ };
+
+ let flags_place = this.project_field(ut, 1)?;
+ let flags = this.read_scalar(&flags_place)?.to_u32()?;
+ let abs_time_flag = flags == abs_time;
+
+ let clock_id_place = this.project_field(ut, 2)?;
+ let clock_id = this.read_scalar(&clock_id_place)?.to_i32()?;
+ let timeout_clock = this.translate_umtx_time_clock_id(clock_id)?;
+
+ interp_ok(Some(UmtxTime { timeout: duration, abs_time: abs_time_flag, timeout_clock }))
+ }
+
+ /// Translate raw FreeBSD clockid to a Miri TimeoutClock.
+ /// FIXME: share this code with the pthread and clock_gettime shims.
+ fn translate_umtx_time_clock_id(&mut self, raw_id: i32) -> InterpResult<'tcx, TimeoutClock> {
+ let this = self.eval_context_mut();
+
+ let timeout = if raw_id == this.eval_libc_i32("CLOCK_REALTIME") {
+ // RealTime clock can't be used in isolation mode.
+ this.check_no_isolation("`_umtx_op` with `CLOCK_REALTIME` timeout")?;
+ TimeoutClock::RealTime
+ } else if raw_id == this.eval_libc_i32("CLOCK_MONOTONIC") {
+ TimeoutClock::Monotonic
+ } else {
+ throw_unsup_format!("unsupported clock id {raw_id}");
+ };
+ interp_ok(timeout)
+ }
+}
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index f8e0c63..fc0f576 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -2,10 +2,9 @@
use std::borrow::Cow;
use std::fs::{
- DirBuilder, File, FileType, Metadata, OpenOptions, ReadDir, read_dir, remove_dir, remove_file,
- rename,
+ DirBuilder, File, FileType, OpenOptions, ReadDir, read_dir, remove_dir, remove_file, rename,
};
-use std::io::{self, ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write};
+use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::time::SystemTime;
@@ -14,98 +13,11 @@
use self::shims::time::system_time_to_duration;
use crate::helpers::check_min_vararg_count;
-use crate::shims::files::{EvalContextExt as _, FileDescription, FileDescriptionRef};
+use crate::shims::files::FileHandle;
use crate::shims::os_str::bytes_to_os_str;
use crate::shims::unix::fd::{FlockOp, UnixFileDescription};
use crate::*;
-#[derive(Debug)]
-struct FileHandle {
- file: File,
- writable: bool,
-}
-
-impl FileDescription for FileHandle {
- fn name(&self) -> &'static str {
- "file"
- }
-
- fn read<'tcx>(
- self: FileDescriptionRef<Self>,
- communicate_allowed: bool,
- ptr: Pointer,
- len: usize,
- ecx: &mut MiriInterpCx<'tcx>,
- finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
- ) -> InterpResult<'tcx> {
- assert!(communicate_allowed, "isolation should have prevented even opening a file");
-
- let result = ecx.read_from_host(&self.file, len, ptr)?;
- finish.call(ecx, result)
- }
-
- fn write<'tcx>(
- self: FileDescriptionRef<Self>,
- communicate_allowed: bool,
- ptr: Pointer,
- len: usize,
- ecx: &mut MiriInterpCx<'tcx>,
- finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
- ) -> InterpResult<'tcx> {
- assert!(communicate_allowed, "isolation should have prevented even opening a file");
-
- let result = ecx.write_to_host(&self.file, len, ptr)?;
- finish.call(ecx, result)
- }
-
- fn seek<'tcx>(
- &self,
- communicate_allowed: bool,
- offset: SeekFrom,
- ) -> InterpResult<'tcx, io::Result<u64>> {
- assert!(communicate_allowed, "isolation should have prevented even opening a file");
- interp_ok((&mut &self.file).seek(offset))
- }
-
- fn close<'tcx>(
- self,
- communicate_allowed: bool,
- _ecx: &mut MiriInterpCx<'tcx>,
- ) -> InterpResult<'tcx, io::Result<()>> {
- assert!(communicate_allowed, "isolation should have prevented even opening a file");
- // We sync the file if it was opened in a mode different than read-only.
- if self.writable {
- // `File::sync_all` does the checks that are done when closing a file. We do this to
- // to handle possible errors correctly.
- let result = self.file.sync_all();
- // Now we actually close the file and return the result.
- drop(self.file);
- interp_ok(result)
- } else {
- // We drop the file, this closes it but ignores any errors
- // produced when closing it. This is done because
- // `File::sync_all` cannot be done over files like
- // `/dev/urandom` which are read-only. Check
- // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439
- // for a deeper discussion.
- drop(self.file);
- interp_ok(Ok(()))
- }
- }
-
- fn metadata<'tcx>(&self) -> InterpResult<'tcx, io::Result<Metadata>> {
- interp_ok(self.file.metadata())
- }
-
- fn is_tty(&self, communicate_allowed: bool) -> bool {
- communicate_allowed && self.file.is_terminal()
- }
-
- fn as_unix(&self) -> &dyn UnixFileDescription {
- self
- }
-}
-
impl UnixFileDescription for FileHandle {
fn pread<'tcx>(
&self,
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 de8bcb5..b489595 100644
--- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs
@@ -153,7 +153,7 @@ fn close<'tcx>(
interp_ok(Ok(()))
}
- fn as_unix(&self) -> &dyn UnixFileDescription {
+ fn as_unix<'tcx>(&self, _ecx: &MiriInterpCx<'tcx>) -> &dyn UnixFileDescription {
self
}
}
@@ -590,7 +590,7 @@ fn check_and_update_one_event_interest<'tcx>(
ecx: &MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, bool> {
// Get the bitmask of ready events for a file description.
- let ready_events_bitmask = fd_ref.as_unix().get_epoll_ready_events()?.get_event_bitmask(ecx);
+ 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
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 936d436..ee7deb8 100644
--- a/src/tools/miri/src/shims/unix/linux_like/eventfd.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/eventfd.rs
@@ -100,7 +100,7 @@ fn write<'tcx>(
eventfd_write(buf_place, self, ecx, finish)
}
- fn as_unix(&self) -> &dyn UnixFileDescription {
+ fn as_unix<'tcx>(&self, _ecx: &MiriInterpCx<'tcx>) -> &dyn UnixFileDescription {
self
}
}
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index 918fd8d..5046e96 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -222,7 +222,7 @@ fn emulate_foreign_item_inner(
this.write_scalar(res, dest)?;
}
- // Futex primitives
+ // Synchronization primitives
"os_sync_wait_on_address" => {
let [addr_op, value_op, size_op, flags_op] =
this.check_shim(abi, Conv::C, link_name, args)?;
@@ -273,7 +273,6 @@ fn emulate_foreign_item_inner(
addr_op, size_op, flags_op, /* all */ true, dest,
)?;
}
-
"os_unfair_lock_lock" => {
let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_lock(lock_op)?;
diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs
index e183bfd..135d8f6 100644
--- a/src/tools/miri/src/shims/unix/unnamed_socket.rs
+++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs
@@ -107,7 +107,7 @@ fn write<'tcx>(
anonsocket_write(self, ptr, len, ecx, finish)
}
- fn as_unix(&self) -> &dyn UnixFileDescription {
+ fn as_unix<'tcx>(&self, _ecx: &MiriInterpCx<'tcx>) -> &dyn UnixFileDescription {
self
}
}
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index fae6170..7d97e33 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -9,14 +9,9 @@
use self::shims::windows::handle::{Handle, PseudoHandle};
use crate::shims::os_str::bytes_to_os_str;
-use crate::shims::windows::handle::HandleError;
use crate::shims::windows::*;
use crate::*;
-// The NTSTATUS STATUS_INVALID_HANDLE (0xC0000008) encoded as a HRESULT by setting the N bit.
-// (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a)
-const STATUS_INVALID_HANDLE: u32 = 0xD0000008;
-
pub fn is_dyn_sym(name: &str) -> bool {
// std does dynamic detection for these symbols
matches!(
@@ -26,57 +21,107 @@ pub fn is_dyn_sym(name: &str) -> bool {
}
#[cfg(windows)]
-fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
+fn win_get_full_path_name<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
// We are on Windows so we can simply let the host do this.
interp_ok(path::absolute(path))
}
#[cfg(unix)]
#[expect(clippy::get_first, clippy::arithmetic_side_effects)]
-fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
- // We are on Unix, so we need to implement parts of the logic ourselves.
+fn win_get_full_path_name<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
+ use std::sync::LazyLock;
+
+ use rustc_data_structures::fx::FxHashSet;
+
+ // We are on Unix, so we need to implement parts of the logic ourselves. `path` will use `/`
+ // separators, and the result should also use `/`.
+ // See <https://chrisdenton.github.io/omnipath/Overview.html#absolute-win32-paths> for more
+ // information about Windows paths.
+ // This does not handle all corner cases correctly, see
+ // <https://github.com/rust-lang/miri/pull/4262#issuecomment-2792168853> for more cursed
+ // examples.
let bytes = path.as_os_str().as_encoded_bytes();
- // If it starts with `//` (these were backslashes but are already converted)
- // then this is a magic special path, we just leave it unchanged.
- if bytes.get(0).copied() == Some(b'/') && bytes.get(1).copied() == Some(b'/') {
+ // If it starts with `//./` or `//?/` then this is a magic special path, we just leave it
+ // unchanged.
+ if bytes.get(0).copied() == Some(b'/')
+ && bytes.get(1).copied() == Some(b'/')
+ && matches!(bytes.get(2), Some(b'.' | b'?'))
+ && bytes.get(3).copied() == Some(b'/')
+ {
return interp_ok(Ok(path.into()));
};
- // Special treatment for Windows' magic filenames: they are treated as being relative to `\\.\`.
- let magic_filenames = &[
- "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8",
- "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
- ];
- if magic_filenames.iter().any(|m| m.as_bytes() == bytes) {
- let mut result: Vec<u8> = br"//./".into();
+ let is_unc = bytes.starts_with(b"//");
+ // Special treatment for Windows' magic filenames: they are treated as being relative to `//./`.
+ static MAGIC_FILENAMES: LazyLock<FxHashSet<&'static str>> = LazyLock::new(|| {
+ FxHashSet::from_iter([
+ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
+ "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
+ ])
+ });
+ if str::from_utf8(bytes).is_ok_and(|s| MAGIC_FILENAMES.contains(&*s.to_ascii_uppercase())) {
+ let mut result: Vec<u8> = b"//./".into();
result.extend(bytes);
return interp_ok(Ok(bytes_to_os_str(&result)?.into()));
}
// Otherwise we try to do something kind of close to what Windows does, but this is probably not
- // right in all cases. We iterate over the components between `/`, and remove trailing `.`,
- // except that trailing `..` remain unchanged.
- let mut result = vec![];
+ // right in all cases.
+ let mut result: Vec<&[u8]> = vec![]; // will be a vecot of components, joined by `/`.
let mut bytes = bytes; // the remaining bytes to process
- loop {
- let len = bytes.iter().position(|&b| b == b'/').unwrap_or(bytes.len());
- let mut component = &bytes[..len];
- if len >= 2 && component[len - 1] == b'.' && component[len - 2] != b'.' {
- // Strip trailing `.`
+ let mut stop = false;
+ while !stop {
+ // Find next component, and advance `bytes`.
+ let mut component = match bytes.iter().position(|&b| b == b'/') {
+ Some(pos) => {
+ let (component, tail) = bytes.split_at(pos);
+ bytes = &tail[1..]; // remove the `/`.
+ component
+ }
+ None => {
+ // There's no more `/`.
+ stop = true;
+ let component = bytes;
+ bytes = &[];
+ component
+ }
+ };
+ // `NUL` and only `NUL` also gets changed to be relative to `//./` later in the path.
+ // (This changed with Windows 11; previously, all magic filenames behaved like this.)
+ // Also, this does not apply to UNC paths.
+ if !is_unc && component.eq_ignore_ascii_case(b"NUL") {
+ let mut result: Vec<u8> = b"//./".into();
+ result.extend(component);
+ return interp_ok(Ok(bytes_to_os_str(&result)?.into()));
+ }
+ // Deal with `..` -- Windows handles this entirely syntactically.
+ if component == b".." {
+ // Remove previous component, unless we are at the "root" already, then just ignore the `..`.
+ let is_root = {
+ // Paths like `/C:`.
+ result.len() == 2 && matches!(result[0], []) && matches!(result[1], [_, b':'])
+ } || {
+ // Paths like `//server/share`
+ result.len() == 4 && matches!(result[0], []) && matches!(result[1], [])
+ };
+ if !is_root {
+ result.pop();
+ }
+ continue;
+ }
+ // Preserve this component.
+ // Strip trailing `.`, but preserve trailing `..`. But not for UNC paths!
+ let len = component.len();
+ if !is_unc && len >= 2 && component[len - 1] == b'.' && component[len - 2] != b'.' {
component = &component[..len - 1];
}
// Add this component to output.
- result.extend(component);
- // Prepare next iteration.
- if len < bytes.len() {
- // There's a component after this; add `/` and process remaining bytes.
- result.push(b'/');
- bytes = &bytes[len + 1..];
- continue;
- } else {
- // This was the last component and it did not have a trailing `/`.
- break;
- }
+ result.push(component);
}
- // Let the host `absolute` function do working-dir handling
+ // Drive letters must be followed by a `/`.
+ if result.len() == 2 && matches!(result[0], []) && matches!(result[1], [_, b':']) {
+ result.push(&[]);
+ }
+ // Let the host `absolute` function do working-dir handling.
+ let result = result.join(&b'/');
interp_ok(path::absolute(bytes_to_os_str(&result)?))
}
@@ -231,7 +276,7 @@ fn emulate_foreign_item_inner(
}
let filename = this.read_path_from_wide_str(filename)?;
- let result = match win_absolute(&filename)? {
+ let result = match win_get_full_path_name(&filename)? {
Err(err) => {
this.set_last_error(err)?;
Scalar::from_u32(0) // return zero upon failure
@@ -246,6 +291,32 @@ fn emulate_foreign_item_inner(
};
this.write_scalar(result, dest)?;
}
+ "CreateFileW" => {
+ let [
+ file_name,
+ desired_access,
+ share_mode,
+ security_attributes,
+ creation_disposition,
+ flags_and_attributes,
+ template_file,
+ ] = this.check_shim(abi, sys_conv, link_name, args)?;
+ let handle = this.CreateFileW(
+ file_name,
+ desired_access,
+ share_mode,
+ security_attributes,
+ creation_disposition,
+ flags_and_attributes,
+ template_file,
+ )?;
+ this.write_scalar(handle.to_scalar(this), dest)?;
+ }
+ "GetFileInformationByHandle" => {
+ let [handle, info] = this.check_shim(abi, sys_conv, link_name, args)?;
+ let res = this.GetFileInformationByHandle(handle, info)?;
+ this.write_scalar(res, dest)?;
+ }
// Allocation
"HeapAlloc" => {
@@ -498,52 +569,37 @@ fn emulate_foreign_item_inner(
"SetThreadDescription" => {
let [handle, name] = this.check_shim(abi, sys_conv, link_name, args)?;
- let handle = this.read_scalar(handle)?;
+ let handle = this.read_handle(handle, "SetThreadDescription")?;
let name = this.read_wide_str(this.read_pointer(name)?)?;
- let thread = match Handle::try_from_scalar(handle, this)? {
- Ok(Handle::Thread(thread)) => Ok(thread),
- Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()),
- Ok(_) | Err(HandleError::InvalidHandle) =>
- this.invalid_handle("SetThreadDescription")?,
- Err(HandleError::ThreadNotFound(e)) => Err(e),
+ let thread = match handle {
+ Handle::Thread(thread) => thread,
+ Handle::Pseudo(PseudoHandle::CurrentThread) => this.active_thread(),
+ _ => this.invalid_handle("SetThreadDescription")?,
};
- let res = match thread {
- Ok(thread) => {
- // FIXME: use non-lossy conversion
- this.set_thread_name(thread, String::from_utf16_lossy(&name).into_bytes());
- Scalar::from_u32(0)
- }
- Err(_) => Scalar::from_u32(STATUS_INVALID_HANDLE),
- };
-
- this.write_scalar(res, dest)?;
+ // FIXME: use non-lossy conversion
+ this.set_thread_name(thread, String::from_utf16_lossy(&name).into_bytes());
+ this.write_scalar(Scalar::from_u32(0), dest)?;
}
"GetThreadDescription" => {
let [handle, name_ptr] = this.check_shim(abi, sys_conv, link_name, args)?;
- let handle = this.read_scalar(handle)?;
+ let handle = this.read_handle(handle, "GetThreadDescription")?;
let name_ptr = this.deref_pointer_as(name_ptr, this.machine.layouts.mut_raw_ptr)?; // the pointer where we should store the ptr to the name
- let thread = match Handle::try_from_scalar(handle, this)? {
- Ok(Handle::Thread(thread)) => Ok(thread),
- Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => Ok(this.active_thread()),
- Ok(_) | Err(HandleError::InvalidHandle) =>
- this.invalid_handle("GetThreadDescription")?,
- Err(HandleError::ThreadNotFound(e)) => Err(e),
+ let thread = match handle {
+ Handle::Thread(thread) => thread,
+ Handle::Pseudo(PseudoHandle::CurrentThread) => this.active_thread(),
+ _ => this.invalid_handle("GetThreadDescription")?,
};
- let (name, res) = match thread {
- Ok(thread) => {
- // Looks like the default thread name is empty.
- let name = this.get_thread_name(thread).unwrap_or(b"").to_owned();
- let name = this.alloc_os_str_as_wide_str(
- bytes_to_os_str(&name)?,
- MiriMemoryKind::WinLocal.into(),
- )?;
- (Scalar::from_maybe_pointer(name, this), Scalar::from_u32(0))
- }
- Err(_) => (Scalar::null_ptr(this), Scalar::from_u32(STATUS_INVALID_HANDLE)),
- };
+ // Looks like the default thread name is empty.
+ let name = this.get_thread_name(thread).unwrap_or(b"").to_owned();
+ let name = this.alloc_os_str_as_wide_str(
+ bytes_to_os_str(&name)?,
+ MiriMemoryKind::WinLocal.into(),
+ )?;
+ let name = Scalar::from_maybe_pointer(name, this);
+ let res = Scalar::from_u32(0);
this.write_scalar(name, &name_ptr)?;
this.write_scalar(res, dest)?;
@@ -638,11 +694,11 @@ fn emulate_foreign_item_inner(
let [handle, filename, size] = this.check_shim(abi, sys_conv, link_name, args)?;
this.check_no_isolation("`GetModuleFileNameW`")?;
- let handle = this.read_target_usize(handle)?;
+ let handle = this.read_handle(handle, "GetModuleFileNameW")?;
let filename = this.read_pointer(filename)?;
let size = this.read_scalar(size)?.to_u32()?;
- if handle != 0 {
+ if handle != Handle::Null {
throw_unsup_format!("`GetModuleFileNameW` only supports the NULL handle");
}
diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs
new file mode 100644
index 0000000..32bab54
--- /dev/null
+++ b/src/tools/miri/src/shims/windows/fs.rs
@@ -0,0 +1,402 @@
+use std::fs::{Metadata, OpenOptions};
+use std::io;
+use std::path::PathBuf;
+use std::time::SystemTime;
+
+use bitflags::bitflags;
+
+use crate::shims::files::{FileDescription, FileHandle};
+use crate::shims::windows::handle::{EvalContextExt as _, Handle};
+use crate::*;
+
+#[derive(Debug)]
+pub struct DirHandle {
+ pub(crate) path: PathBuf,
+}
+
+impl FileDescription for DirHandle {
+ fn name(&self) -> &'static str {
+ "directory"
+ }
+
+ fn metadata<'tcx>(&self) -> InterpResult<'tcx, io::Result<Metadata>> {
+ interp_ok(self.path.metadata())
+ }
+
+ fn close<'tcx>(
+ self,
+ _communicate_allowed: bool,
+ _ecx: &mut MiriInterpCx<'tcx>,
+ ) -> InterpResult<'tcx, io::Result<()>> {
+ interp_ok(Ok(()))
+ }
+}
+
+/// Windows supports handles without any read/write/delete permissions - these handles can get
+/// metadata, but little else. We represent that by storing the metadata from the time the handle
+/// was opened.
+#[derive(Debug)]
+pub struct MetadataHandle {
+ pub(crate) meta: Metadata,
+}
+
+impl FileDescription for MetadataHandle {
+ fn name(&self) -> &'static str {
+ "metadata-only"
+ }
+
+ fn metadata<'tcx>(&self) -> InterpResult<'tcx, io::Result<Metadata>> {
+ interp_ok(Ok(self.meta.clone()))
+ }
+
+ fn close<'tcx>(
+ self,
+ _communicate_allowed: bool,
+ _ecx: &mut MiriInterpCx<'tcx>,
+ ) -> InterpResult<'tcx, io::Result<()>> {
+ interp_ok(Ok(()))
+ }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+enum CreationDisposition {
+ CreateAlways,
+ CreateNew,
+ OpenAlways,
+ OpenExisting,
+ TruncateExisting,
+}
+
+impl CreationDisposition {
+ fn new<'tcx>(
+ value: u32,
+ ecx: &mut MiriInterpCx<'tcx>,
+ ) -> InterpResult<'tcx, CreationDisposition> {
+ let create_always = ecx.eval_windows_u32("c", "CREATE_ALWAYS");
+ let create_new = ecx.eval_windows_u32("c", "CREATE_NEW");
+ let open_always = ecx.eval_windows_u32("c", "OPEN_ALWAYS");
+ let open_existing = ecx.eval_windows_u32("c", "OPEN_EXISTING");
+ let truncate_existing = ecx.eval_windows_u32("c", "TRUNCATE_EXISTING");
+
+ let out = if value == create_always {
+ CreationDisposition::CreateAlways
+ } else if value == create_new {
+ CreationDisposition::CreateNew
+ } else if value == open_always {
+ CreationDisposition::OpenAlways
+ } else if value == open_existing {
+ CreationDisposition::OpenExisting
+ } else if value == truncate_existing {
+ CreationDisposition::TruncateExisting
+ } else {
+ throw_unsup_format!("CreateFileW: Unsupported creation disposition: {value}");
+ };
+ interp_ok(out)
+ }
+}
+
+bitflags! {
+ #[derive(PartialEq)]
+ struct FileAttributes: u32 {
+ const ZERO = 0;
+ const NORMAL = 1 << 0;
+ /// This must be passed to allow getting directory handles. If not passed, we error on trying
+ /// to open directories
+ const BACKUP_SEMANTICS = 1 << 1;
+ /// Open a reparse point as a regular file - this is basically similar to 'readlink' in Unix
+ /// terminology. A reparse point is a file with custom logic when navigated to, of which
+ /// a symlink is one specific example.
+ const OPEN_REPARSE = 1 << 2;
+ }
+}
+
+impl FileAttributes {
+ fn new<'tcx>(
+ mut value: u32,
+ ecx: &mut MiriInterpCx<'tcx>,
+ ) -> InterpResult<'tcx, FileAttributes> {
+ let file_attribute_normal = ecx.eval_windows_u32("c", "FILE_ATTRIBUTE_NORMAL");
+ let file_flag_backup_semantics = ecx.eval_windows_u32("c", "FILE_FLAG_BACKUP_SEMANTICS");
+ let file_flag_open_reparse_point =
+ ecx.eval_windows_u32("c", "FILE_FLAG_OPEN_REPARSE_POINT");
+
+ let mut out = FileAttributes::ZERO;
+ if value & file_flag_backup_semantics != 0 {
+ value &= !file_flag_backup_semantics;
+ out |= FileAttributes::BACKUP_SEMANTICS;
+ }
+ if value & file_flag_open_reparse_point != 0 {
+ value &= !file_flag_open_reparse_point;
+ out |= FileAttributes::OPEN_REPARSE;
+ }
+ if value & file_attribute_normal != 0 {
+ value &= !file_attribute_normal;
+ out |= FileAttributes::NORMAL;
+ }
+
+ if value != 0 {
+ throw_unsup_format!("CreateFileW: Unsupported flags_and_attributes: {value}");
+ }
+
+ if out == FileAttributes::ZERO {
+ // NORMAL is equivalent to 0. Avoid needing to check both cases by unifying the two.
+ out = FileAttributes::NORMAL;
+ }
+ interp_ok(out)
+ }
+}
+
+impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
+#[allow(non_snake_case)]
+pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+ fn CreateFileW(
+ &mut self,
+ file_name: &OpTy<'tcx>, // LPCWSTR
+ desired_access: &OpTy<'tcx>, // DWORD
+ share_mode: &OpTy<'tcx>, // DWORD
+ security_attributes: &OpTy<'tcx>, // LPSECURITY_ATTRIBUTES
+ creation_disposition: &OpTy<'tcx>, // DWORD
+ flags_and_attributes: &OpTy<'tcx>, // DWORD
+ template_file: &OpTy<'tcx>, // HANDLE
+ ) -> InterpResult<'tcx, Handle> {
+ // ^ Returns HANDLE
+ use CreationDisposition::*;
+
+ let this = self.eval_context_mut();
+ this.assert_target_os("windows", "CreateFileW");
+ this.check_no_isolation("`CreateFileW`")?;
+
+ // This function appears to always set the error to 0. This is important for some flag
+ // combinations, which may set error code on success.
+ this.set_last_error(IoError::Raw(Scalar::from_i32(0)))?;
+
+ let file_name = this.read_path_from_wide_str(this.read_pointer(file_name)?)?;
+ let mut desired_access = this.read_scalar(desired_access)?.to_u32()?;
+ let share_mode = this.read_scalar(share_mode)?.to_u32()?;
+ let security_attributes = this.read_pointer(security_attributes)?;
+ let creation_disposition = this.read_scalar(creation_disposition)?.to_u32()?;
+ let flags_and_attributes = this.read_scalar(flags_and_attributes)?.to_u32()?;
+ let template_file = this.read_target_usize(template_file)?;
+
+ let generic_read = this.eval_windows_u32("c", "GENERIC_READ");
+ let generic_write = this.eval_windows_u32("c", "GENERIC_WRITE");
+
+ let file_share_delete = this.eval_windows_u32("c", "FILE_SHARE_DELETE");
+ let file_share_read = this.eval_windows_u32("c", "FILE_SHARE_READ");
+ let file_share_write = this.eval_windows_u32("c", "FILE_SHARE_WRITE");
+
+ let creation_disposition = CreationDisposition::new(creation_disposition, this)?;
+ let attributes = FileAttributes::new(flags_and_attributes, this)?;
+
+ if share_mode != (file_share_delete | file_share_read | file_share_write) {
+ throw_unsup_format!("CreateFileW: Unsupported share mode: {share_mode}");
+ }
+ if !this.ptr_is_null(security_attributes)? {
+ throw_unsup_format!("CreateFileW: Security attributes are not supported");
+ }
+
+ if attributes.contains(FileAttributes::OPEN_REPARSE) && creation_disposition == CreateAlways
+ {
+ throw_machine_stop!(TerminationInfo::Abort("Invalid CreateFileW argument combination: FILE_FLAG_OPEN_REPARSE_POINT with CREATE_ALWAYS".to_string()));
+ }
+
+ if template_file != 0 {
+ throw_unsup_format!("CreateFileW: Template files are not supported");
+ }
+
+ // We need to know if the file is a directory to correctly open directory handles.
+ // This is racy, but currently the stdlib doesn't appear to offer a better solution.
+ let is_dir = file_name.is_dir();
+
+ // BACKUP_SEMANTICS is how Windows calls the act of opening a directory handle.
+ if !attributes.contains(FileAttributes::BACKUP_SEMANTICS) && is_dir {
+ this.set_last_error(IoError::WindowsError("ERROR_ACCESS_DENIED"))?;
+ return interp_ok(Handle::Invalid);
+ }
+
+ let desired_read = desired_access & generic_read != 0;
+ let desired_write = desired_access & generic_write != 0;
+
+ let mut options = OpenOptions::new();
+ if desired_read {
+ desired_access &= !generic_read;
+ options.read(true);
+ }
+ if desired_write {
+ desired_access &= !generic_write;
+ options.write(true);
+ }
+
+ if desired_access != 0 {
+ throw_unsup_format!(
+ "CreateFileW: Unsupported bits set for access mode: {desired_access:#x}"
+ );
+ }
+
+ // Per the documentation:
+ // If the specified file exists and is writable, the function truncates the file,
+ // the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS.
+ // If the specified file does not exist and is a valid path, a new file is created,
+ // the function succeeds, and the last-error code is set to zero.
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
+ //
+ // This is racy, but there doesn't appear to be an std API that both succeeds if a
+ // file exists but tells us it isn't new. Either we accept racing one way or another,
+ // or we use an iffy heuristic like file creation time. This implementation prefers
+ // to fail in the direction of erroring more often.
+ if let CreateAlways | OpenAlways = creation_disposition
+ && file_name.exists()
+ {
+ this.set_last_error(IoError::WindowsError("ERROR_ALREADY_EXISTS"))?;
+ }
+
+ let handle = if is_dir {
+ // Open this as a directory.
+ let fd_num = this.machine.fds.insert_new(DirHandle { path: file_name });
+ Ok(Handle::File(fd_num))
+ } else if creation_disposition == OpenExisting && !(desired_read || desired_write) {
+ // Windows supports handles with no permissions. These allow things such as reading
+ // metadata, but not file content.
+ file_name.metadata().map(|meta| {
+ let fd_num = this.machine.fds.insert_new(MetadataHandle { meta });
+ Handle::File(fd_num)
+ })
+ } else {
+ // Open this as a standard file.
+ match creation_disposition {
+ CreateAlways | OpenAlways => {
+ options.create(true);
+ if creation_disposition == CreateAlways {
+ options.truncate(true);
+ }
+ }
+ CreateNew => {
+ options.create_new(true);
+ // Per `create_new` documentation:
+ // The file must be opened with write or append access in order to create a new file.
+ // https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new
+ if !desired_write {
+ options.append(true);
+ }
+ }
+ OpenExisting => {} // Default options
+ TruncateExisting => {
+ options.truncate(true);
+ }
+ }
+
+ options.open(file_name).map(|file| {
+ let fd_num =
+ this.machine.fds.insert_new(FileHandle { file, writable: desired_write });
+ Handle::File(fd_num)
+ })
+ };
+
+ match handle {
+ Ok(handle) => interp_ok(handle),
+ Err(e) => {
+ this.set_last_error(e)?;
+ interp_ok(Handle::Invalid)
+ }
+ }
+ }
+
+ fn GetFileInformationByHandle(
+ &mut self,
+ file: &OpTy<'tcx>, // HANDLE
+ file_information: &OpTy<'tcx>, // LPBY_HANDLE_FILE_INFORMATION
+ ) -> InterpResult<'tcx, Scalar> {
+ // ^ Returns BOOL (i32 on Windows)
+ let this = self.eval_context_mut();
+ this.assert_target_os("windows", "GetFileInformationByHandle");
+ this.check_no_isolation("`GetFileInformationByHandle`")?;
+
+ let file = this.read_handle(file, "GetFileInformationByHandle")?;
+ let file_information = this.deref_pointer_as(
+ file_information,
+ this.windows_ty_layout("BY_HANDLE_FILE_INFORMATION"),
+ )?;
+
+ let fd_num = if let Handle::File(fd_num) = file {
+ fd_num
+ } else {
+ this.invalid_handle("GetFileInformationByHandle")?
+ };
+
+ let Some(desc) = this.machine.fds.get(fd_num) else {
+ this.invalid_handle("GetFileInformationByHandle")?
+ };
+
+ let metadata = match desc.metadata()? {
+ Ok(meta) => meta,
+ Err(e) => {
+ this.set_last_error(e)?;
+ return interp_ok(this.eval_windows("c", "FALSE"));
+ }
+ };
+
+ let size = metadata.len();
+
+ let file_type = metadata.file_type();
+ let attributes = if file_type.is_dir() {
+ this.eval_windows_u32("c", "FILE_ATTRIBUTE_DIRECTORY")
+ } else if file_type.is_file() {
+ this.eval_windows_u32("c", "FILE_ATTRIBUTE_NORMAL")
+ } else {
+ this.eval_windows_u32("c", "FILE_ATTRIBUTE_DEVICE")
+ };
+
+ // Per the Windows documentation:
+ // "If the underlying file system does not support the [...] time, this member is zero (0)."
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
+ let created = extract_windows_epoch(this, metadata.created())?.unwrap_or((0, 0));
+ let accessed = extract_windows_epoch(this, metadata.accessed())?.unwrap_or((0, 0));
+ let written = extract_windows_epoch(this, metadata.modified())?.unwrap_or((0, 0));
+
+ this.write_int_fields_named(&[("dwFileAttributes", attributes.into())], &file_information)?;
+ write_filetime_field(this, &file_information, "ftCreationTime", created)?;
+ write_filetime_field(this, &file_information, "ftLastAccessTime", accessed)?;
+ write_filetime_field(this, &file_information, "ftLastWriteTime", written)?;
+ this.write_int_fields_named(
+ &[
+ ("dwVolumeSerialNumber", 0),
+ ("nFileSizeHigh", (size >> 32).into()),
+ ("nFileSizeLow", (size & 0xFFFFFFFF).into()),
+ ("nNumberOfLinks", 1),
+ ("nFileIndexHigh", 0),
+ ("nFileIndexLow", 0),
+ ],
+ &file_information,
+ )?;
+
+ interp_ok(this.eval_windows("c", "TRUE"))
+ }
+}
+
+/// Windows FILETIME is measured in 100-nanosecs since 1601
+fn extract_windows_epoch<'tcx>(
+ ecx: &MiriInterpCx<'tcx>,
+ time: io::Result<SystemTime>,
+) -> InterpResult<'tcx, Option<(u32, u32)>> {
+ match time.ok() {
+ Some(time) => {
+ let duration = ecx.system_time_since_windows_epoch(&time)?;
+ let duration_ticks = ecx.windows_ticks_for(duration)?;
+ #[allow(clippy::cast_possible_truncation)]
+ interp_ok(Some((duration_ticks as u32, (duration_ticks >> 32) as u32)))
+ }
+ None => interp_ok(None),
+ }
+}
+
+fn write_filetime_field<'tcx>(
+ cx: &mut MiriInterpCx<'tcx>,
+ val: &MPlaceTy<'tcx>,
+ name: &str,
+ (low, high): (u32, u32),
+) -> InterpResult<'tcx> {
+ cx.write_int_fields_named(
+ &[("dwLowDateTime", low.into()), ("dwHighDateTime", high.into())],
+ &cx.project_field_named(val, name)?,
+ )
+}
diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs
index c4eb11f..eec6c62 100644
--- a/src/tools/miri/src/shims/windows/handle.rs
+++ b/src/tools/miri/src/shims/windows/handle.rs
@@ -3,6 +3,7 @@
use rustc_abi::HasDataLayout;
use crate::concurrency::thread::ThreadNotFound;
+use crate::shims::files::FdNum;
use crate::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -16,6 +17,8 @@ pub enum Handle {
Null,
Pseudo(PseudoHandle),
Thread(ThreadId),
+ File(FdNum),
+ Invalid,
}
impl PseudoHandle {
@@ -47,12 +50,18 @@ impl Handle {
const NULL_DISCRIMINANT: u32 = 0;
const PSEUDO_DISCRIMINANT: u32 = 1;
const THREAD_DISCRIMINANT: u32 = 2;
+ const FILE_DISCRIMINANT: u32 = 3;
+ // Chosen to ensure Handle::Invalid encodes to -1. Update this value if there are ever more than
+ // 8 discriminants.
+ const INVALID_DISCRIMINANT: u32 = 7;
fn discriminant(self) -> u32 {
match self {
Self::Null => Self::NULL_DISCRIMINANT,
Self::Pseudo(_) => Self::PSEUDO_DISCRIMINANT,
Self::Thread(_) => Self::THREAD_DISCRIMINANT,
+ Self::File(_) => Self::FILE_DISCRIMINANT,
+ Self::Invalid => Self::INVALID_DISCRIMINANT,
}
}
@@ -61,17 +70,27 @@ fn data(self) -> u32 {
Self::Null => 0,
Self::Pseudo(pseudo_handle) => pseudo_handle.value(),
Self::Thread(thread) => thread.to_u32(),
+ #[expect(clippy::cast_sign_loss)]
+ Self::File(fd) => fd as u32,
+ // INVALID_HANDLE_VALUE is -1. This fact is explicitly declared or implied in several
+ // pages of Windows documentation.
+ // 1: https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.safehandles.safefilehandle?view=net-9.0
+ // 2: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
+ Self::Invalid => 0x1FFFFFFF,
}
}
fn packed_disc_size() -> u32 {
- // ceil(log2(x)) is how many bits it takes to store x numbers
+ // ceil(log2(x)) is how many bits it takes to store x numbers.
+ // We ensure that INVALID_HANDLE_VALUE (0xFFFFFFFF) decodes to Handle::Invalid.
+ // see https://devblogs.microsoft.com/oldnewthing/20230914-00/?p=108766 for more detail on
+ // INVALID_HANDLE_VALUE.
let variant_count = variant_count::<Self>();
- // however, std's ilog2 is floor(log2(x))
+ // However, std's ilog2 is floor(log2(x)).
let floor_log2 = variant_count.ilog2();
- // we need to add one for non powers of two to compensate for the difference
+ // We need to add one for non powers of two to compensate for the difference.
#[expect(clippy::arithmetic_side_effects)] // cannot overflow
if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 }
}
@@ -105,6 +124,13 @@ fn new(discriminant: u32, data: u32) -> Option<Self> {
Self::NULL_DISCRIMINANT if data == 0 => Some(Self::Null),
Self::PSEUDO_DISCRIMINANT => Some(Self::Pseudo(PseudoHandle::from_value(data)?)),
Self::THREAD_DISCRIMINANT => Some(Self::Thread(ThreadId::new_unchecked(data))),
+ #[expect(clippy::cast_possible_wrap)]
+ Self::FILE_DISCRIMINANT => {
+ // This cast preserves all bits.
+ assert_eq!(size_of_val(&data), size_of::<FdNum>());
+ Some(Self::File(data as FdNum))
+ }
+ Self::INVALID_DISCRIMINANT => Some(Self::Invalid),
_ => None,
}
}
@@ -139,7 +165,7 @@ pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar {
/// Structurally invalid handles return [`HandleError::InvalidHandle`].
/// If the handle is structurally valid but semantically invalid, e.g. a for non-existent thread
/// ID, returns [`HandleError::ThreadNotFound`].
- pub fn try_from_scalar<'tcx>(
+ fn try_from_scalar<'tcx>(
handle: Scalar,
cx: &MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, Result<Self, HandleError>> {
@@ -171,6 +197,27 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
#[allow(non_snake_case)]
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+ /// Convert a scalar into a structured `Handle`.
+ /// If the handle is invalid, or references a non-existent item, execution is aborted.
+ #[track_caller]
+ fn read_handle(&self, handle: &OpTy<'tcx>, function_name: &str) -> InterpResult<'tcx, Handle> {
+ let this = self.eval_context_ref();
+ let handle = this.read_scalar(handle)?;
+ match Handle::try_from_scalar(handle, this)? {
+ Ok(handle) => interp_ok(handle),
+ Err(HandleError::InvalidHandle) =>
+ throw_machine_stop!(TerminationInfo::Abort(format!(
+ "invalid handle {} passed to {function_name}",
+ handle.to_target_isize(this)?,
+ ))),
+ Err(HandleError::ThreadNotFound(_)) =>
+ throw_machine_stop!(TerminationInfo::Abort(format!(
+ "invalid thread ID {} passed to {function_name}",
+ handle.to_target_isize(this)?,
+ ))),
+ }
+ }
+
fn invalid_handle(&mut self, function_name: &str) -> InterpResult<'tcx, !> {
throw_machine_stop!(TerminationInfo::Abort(format!(
"invalid handle passed to `{function_name}`"
@@ -180,15 +227,38 @@ fn invalid_handle(&mut self, function_name: &str) -> InterpResult<'tcx, !> {
fn CloseHandle(&mut self, handle_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();
- let handle = this.read_scalar(handle_op)?;
- let ret = match Handle::try_from_scalar(handle, this)? {
- Ok(Handle::Thread(thread)) => {
+ let handle = this.read_handle(handle_op, "CloseHandle")?;
+ let ret = match handle {
+ Handle::Thread(thread) => {
this.detach_thread(thread, /*allow_terminated_joined*/ true)?;
this.eval_windows("c", "TRUE")
}
+ Handle::File(fd_num) =>
+ if let Some(fd) = this.machine.fds.remove(fd_num) {
+ let err = fd.close_ref(this.machine.communicate(), this)?;
+ if let Err(e) = err {
+ this.set_last_error(e)?;
+ this.eval_windows("c", "FALSE")
+ } else {
+ this.eval_windows("c", "TRUE")
+ }
+ } else {
+ this.invalid_handle("CloseHandle")?
+ },
_ => this.invalid_handle("CloseHandle")?,
};
interp_ok(ret)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_invalid_encoding() {
+ // Ensure the invalid handle encodes to `u32::MAX`/`INVALID_HANDLE_VALUE`.
+ assert_eq!(Handle::Invalid.to_packed(), u32::MAX)
+ }
+}
diff --git a/src/tools/miri/src/shims/windows/mod.rs b/src/tools/miri/src/shims/windows/mod.rs
index 892bd69..442c5a0 100644
--- a/src/tools/miri/src/shims/windows/mod.rs
+++ b/src/tools/miri/src/shims/windows/mod.rs
@@ -1,12 +1,14 @@
pub mod foreign_items;
mod env;
+mod fs;
mod handle;
mod sync;
mod thread;
// All the Windows-specific extension traits
pub use self::env::{EvalContextExt as _, WindowsEnvVars};
+pub use self::fs::EvalContextExt as _;
pub use self::handle::EvalContextExt as _;
pub use self::sync::EvalContextExt as _;
pub use self::thread::EvalContextExt as _;
diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs
index 5db5540..d5f9ed4 100644
--- a/src/tools/miri/src/shims/windows/thread.rs
+++ b/src/tools/miri/src/shims/windows/thread.rs
@@ -62,14 +62,14 @@ fn WaitForSingleObject(
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();
- let handle = this.read_scalar(handle_op)?;
+ let handle = this.read_handle(handle_op, "WaitForSingleObject")?;
let timeout = this.read_scalar(timeout_op)?.to_u32()?;
- let thread = match Handle::try_from_scalar(handle, this)? {
- Ok(Handle::Thread(thread)) => thread,
+ let thread = match handle {
+ Handle::Thread(thread) => thread,
// Unlike on posix, the outcome of joining the current thread is not documented.
// On current Windows, it just deadlocks.
- Ok(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.active_thread(),
+ Handle::Pseudo(PseudoHandle::CurrentThread) => this.active_thread(),
_ => this.invalid_handle("WaitForSingleObject")?,
};
diff --git a/src/tools/miri/test-cargo-miri/Cargo.lock b/src/tools/miri/test-cargo-miri/Cargo.lock
index 8f618e7..3211942 100644
--- a/src/tools/miri/test-cargo-miri/Cargo.lock
+++ b/src/tools/miri/test-cargo-miri/Cargo.lock
@@ -1,12 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "autocfg"
-version = "1.2.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "byteorder"
@@ -96,15 +96,15 @@
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "proc-macro2"
-version = "1.0.79"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
@@ -129,6 +129,6 @@
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
diff --git a/src/tools/miri/test-cargo-miri/Cargo.toml b/src/tools/miri/test-cargo-miri/Cargo.toml
index 574f1d0..f5092a4 100644
--- a/src/tools/miri/test-cargo-miri/Cargo.toml
+++ b/src/tools/miri/test-cargo-miri/Cargo.toml
@@ -6,7 +6,7 @@
name = "cargo-miri-test"
version = "0.1.0"
authors = ["Miri Team"]
-edition = "2018"
+edition = "2024"
[dependencies]
byteorder = "1.0"
diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py
index 5b77092..a9d09ac 100755
--- a/src/tools/miri/test-cargo-miri/run-test.py
+++ b/src/tools/miri/test-cargo-miri/run-test.py
@@ -136,7 +136,7 @@
cargo_miri("run") + ["--target-dir=custom-run", "--", "--target-dir=target/custom-run"],
"run.args.stdout.ref", "run.custom-target-dir.stderr.ref",
)
- test("`cargo miri run --package=test-local-crate-detection` (test local crate detection)",
+ test("`cargo miri run` (test local crate detection)",
cargo_miri("run") + ["--package=test-local-crate-detection"],
"run.local_crate.stdout.ref", "run.local_crate.stderr.ref",
)
@@ -147,49 +147,46 @@
default_ref = "test.cross-target.stdout.ref" if is_foreign else "test.default.stdout.ref"
filter_ref = "test.filter.cross-target.stdout.ref" if is_foreign else "test.filter.stdout.ref"
- # macOS needs permissive provenance inside getrandom_1.
test("`cargo miri test`",
cargo_miri("test"),
- default_ref, "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=4242"},
+ default_ref, "test.empty.ref",
+ env={'MIRIFLAGS': "-Zmiri-seed=4242"},
)
test("`cargo miri test` (no isolation, no doctests)",
cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml`
- "test.cross-target.stdout.ref", "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-disable-isolation"},
+ "test.cross-target.stdout.ref", "test.empty.ref",
+ env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
)
test("`cargo miri test` (with filter)",
cargo_miri("test") + ["--", "--format=pretty", "pl"],
- filter_ref, "test.stderr-empty.ref",
+ filter_ref, "test.empty.ref",
)
test("`cargo miri test` (test target)",
cargo_miri("test") + ["--test", "test", "--", "--format=pretty"],
- "test.test-target.stdout.ref", "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance"},
+ "test.test-target.stdout.ref", "test.empty.ref",
)
test("`cargo miri test` (bin target)",
cargo_miri("test") + ["--bin", "cargo-miri-test", "--", "--format=pretty"],
- "test.bin-target.stdout.ref", "test.stderr-empty.ref",
+ "test.bin-target.stdout.ref", "test.empty.ref",
)
test("`cargo miri t` (subcrate, no isolation)",
cargo_miri("t") + ["-p", "subcrate"],
- "test.subcrate.stdout.ref", "test.stderr-proc-macro.ref",
+ "test.subcrate.cross-target.stdout.ref" if is_foreign else "test.subcrate.stdout.ref",
+ "test.empty.ref",
env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
)
- test("`cargo miri test` (subcrate, doctests)",
- cargo_miri("test") + ["-p", "subcrate", "--doc"],
- "test.stdout-empty.ref", "test.stderr-proc-macro-doctest.ref",
+ test("`cargo miri test` (proc-macro crate)",
+ cargo_miri("test") + ["-p", "proc_macro_crate"],
+ "test.empty.ref", "test.proc-macro.stderr.ref",
)
test("`cargo miri test` (custom target dir)",
cargo_miri("test") + ["--target-dir=custom-test"],
- default_ref, "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance"},
+ default_ref, "test.empty.ref",
)
del os.environ["CARGO_TARGET_DIR"] # this overrides `build.target-dir` passed by `--config`, so unset it
test("`cargo miri test` (config-cli)",
cargo_miri("test") + ["--config=build.target-dir=\"config-cli\""],
- default_ref, "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance"},
+ default_ref, "test.empty.ref",
)
if ARGS.multi_target:
test_cargo_miri_multi_target()
@@ -198,8 +195,7 @@
def test_cargo_miri_multi_target():
test("`cargo miri test` (multiple targets)",
cargo_miri("test", targets = ["aarch64-unknown-linux-gnu", "s390x-unknown-linux-gnu"]),
- "test.multiple_targets.stdout.ref", "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance"},
+ "test.multiple_targets.stdout.ref", "test.empty.ref",
)
args_parser = argparse.ArgumentParser(description='`cargo miri` testing')
diff --git a/src/tools/miri/test-cargo-miri/src/lib.rs b/src/tools/miri/test-cargo-miri/src/lib.rs
index 003341d0..3b63f8a 100644
--- a/src/tools/miri/test-cargo-miri/src/lib.rs
+++ b/src/tools/miri/test-cargo-miri/src/lib.rs
@@ -26,7 +26,8 @@
///
/// let _val = Fail::<i32>::C;
/// ```
-#[no_mangle]
+// This is imported in `main.rs`.
+#[unsafe(no_mangle)]
pub fn make_true() -> bool {
proc_macro_crate::use_the_dependency!();
issue_1567::use_the_dependency();
diff --git a/src/tools/miri/test-cargo-miri/src/main.rs b/src/tools/miri/test-cargo-miri/src/main.rs
index efe95bf..00a239a 100644
--- a/src/tools/miri/test-cargo-miri/src/main.rs
+++ b/src/tools/miri/test-cargo-miri/src/main.rs
@@ -30,7 +30,7 @@ fn host_to_target_path(path: String) -> PathBuf {
let mut out = Vec::with_capacity(1024);
unsafe {
- extern "Rust" {
+ unsafe extern "Rust" {
fn miri_host_to_target_path(
path: *const c_char,
out: *mut c_char,
@@ -81,7 +81,7 @@ fn exported_symbol() {
// Test calling exported symbols in (transitive) dependencies.
// Repeat calls to make sure the `Instance` cache is not broken.
for _ in 0..3 {
- extern "Rust" {
+ unsafe extern "Rust" {
fn exported_symbol() -> i32;
fn assoc_fn_as_exported_symbol() -> i32;
fn make_true() -> bool;
diff --git a/src/tools/miri/test-cargo-miri/subcrate/Cargo.toml b/src/tools/miri/test-cargo-miri/subcrate/Cargo.toml
index 06b1ce1..f2f6360 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/Cargo.toml
+++ b/src/tools/miri/test-cargo-miri/subcrate/Cargo.toml
@@ -2,11 +2,11 @@
name = "subcrate"
version = "0.1.0"
authors = ["Miri Team"]
+# This is deliberately *not* on the 2024 edition to ensure doctests keep working
+# on old editions.
edition = "2018"
[lib]
-proc-macro = true
-doctest = false
[[bin]]
name = "subcrate"
diff --git a/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
index 98c22fe..b9278c5 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs
@@ -1,16 +1,8 @@
-// This is a proc-macro crate.
-
-extern crate proc_macro; // make sure proc_macro is in the sysroot
-
-#[cfg(doctest)]
-compile_error!("rustdoc should not touch me");
-
-#[cfg(miri)]
-compile_error!("Miri should not touch me");
-
-use proc_macro::TokenStream;
-
-#[proc_macro]
-pub fn make_answer(_item: TokenStream) -> TokenStream {
- "fn answer() -> u32 { 42 }".parse().unwrap()
+/// Doc-test test
+///
+/// ```rust
+/// assert!(subcrate::make_true());
+/// ```
+pub fn make_true() -> bool {
+ true
}
diff --git a/src/tools/miri/test-cargo-miri/test.stderr-empty.ref b/src/tools/miri/test-cargo-miri/test.empty.ref
similarity index 100%
rename from src/tools/miri/test-cargo-miri/test.stderr-empty.ref
rename to src/tools/miri/test-cargo-miri/test.empty.ref
diff --git a/src/tools/miri/test-cargo-miri/test.proc-macro.stderr.ref b/src/tools/miri/test-cargo-miri/test.proc-macro.stderr.ref
new file mode 100644
index 0000000..b954742
--- /dev/null
+++ b/src/tools/miri/test-cargo-miri/test.proc-macro.stderr.ref
@@ -0,0 +1,2 @@
+Running unit tests of `proc-macro` crates is not currently supported by Miri.
+Running doctests of `proc-macro` crates is not currently supported by Miri.
diff --git a/src/tools/miri/test-cargo-miri/test.stderr-proc-macro-doctest.ref b/src/tools/miri/test-cargo-miri/test.stderr-proc-macro-doctest.ref
deleted file mode 100644
index ca5e3a2..0000000
--- a/src/tools/miri/test-cargo-miri/test.stderr-proc-macro-doctest.ref
+++ /dev/null
@@ -1 +0,0 @@
-Running doctests of `proc-macro` crates is not currently supported by Miri.
diff --git a/src/tools/miri/test-cargo-miri/test.stderr-proc-macro.ref b/src/tools/miri/test-cargo-miri/test.stderr-proc-macro.ref
deleted file mode 100644
index 4983250..0000000
--- a/src/tools/miri/test-cargo-miri/test.stderr-proc-macro.ref
+++ /dev/null
@@ -1 +0,0 @@
-Running unit tests of `proc-macro` crates is not currently supported by Miri.
diff --git a/src/tools/miri/test-cargo-miri/test.stdout-empty.ref b/src/tools/miri/test-cargo-miri/test.stdout-empty.ref
deleted file mode 100644
index e69de29..0000000
--- a/src/tools/miri/test-cargo-miri/test.stdout-empty.ref
+++ /dev/null
diff --git a/src/tools/miri/test-cargo-miri/test.subcrate.cross-target.stdout.ref b/src/tools/miri/test-cargo-miri/test.subcrate.cross-target.stdout.ref
new file mode 100644
index 0000000..436e6e4
--- /dev/null
+++ b/src/tools/miri/test-cargo-miri/test.subcrate.cross-target.stdout.ref
@@ -0,0 +1,11 @@
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
+subcrate testing
diff --git a/src/tools/miri/test-cargo-miri/test.subcrate.stdout.ref b/src/tools/miri/test-cargo-miri/test.subcrate.stdout.ref
index e50838e..c7c7bc8 100644
--- a/src/tools/miri/test-cargo-miri/test.subcrate.stdout.ref
+++ b/src/tools/miri/test-cargo-miri/test.subcrate.stdout.ref
@@ -3,4 +3,14 @@
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
subcrate testing
+
+running 1 test
+.
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index af92f9d..24a8efc 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -4,60 +4,51 @@
[[package]]
name = "addr2line"
-version = "0.22.0"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
[[package]]
-name = "adler"
-version = "1.0.2"
+name = "adler2"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "backtrace"
-version = "0.3.73"
+version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
- "cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
+ "windows-targets",
]
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytes"
-version = "1.7.1"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
-
-[[package]]
-name = "cc"
-version = "1.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
-dependencies = [
- "shlex",
-]
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cfg-if"
@@ -67,19 +58,19 @@
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
- "windows-sys",
+ "windows-sys 0.59.0",
]
[[package]]
name = "fastrand"
-version = "2.1.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "getrandom"
@@ -107,21 +98,21 @@
[[package]]
name = "getrandom"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
- "wasi 0.13.3+wasi-0.2.2",
- "windows-targets",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "gimli"
-version = "0.29.0"
+version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hermit-abi"
@@ -131,30 +122,31 @@
[[package]]
name = "js-sys"
-version = "0.3.69"
+version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
+ "once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
-version = "0.2.161"
+version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
@@ -164,23 +156,22 @@
[[package]]
name = "miniz_oxide"
-version = "0.7.4"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
+checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
dependencies = [
- "adler",
+ "adler2",
]
[[package]]
name = "mio"
-version = "1.0.1"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
- "hermit-abi",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -190,13 +181,13 @@
"cfg-if",
"getrandom 0.1.16",
"getrandom 0.2.15",
- "getrandom 0.3.1",
+ "getrandom 0.3.2",
"libc",
"num_cpus",
"page_size",
"tempfile",
"tokio",
- "windows-sys",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -211,18 +202,18 @@
[[package]]
name = "object"
-version = "0.36.2"
+version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "page_size"
@@ -236,29 +227,35 @@
[[package]]
name = "pin-project-lite"
-version = "0.2.14"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.36"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -266,24 +263,18 @@
[[package]]
name = "rustix"
-version = "0.38.34"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.59.0",
]
[[package]]
-name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -294,19 +285,19 @@
[[package]]
name = "socket2"
-version = "0.5.7"
+version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
+checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
dependencies = [
"libc",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
name = "syn"
-version = "2.0.72"
+version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@@ -315,22 +306,22 @@
[[package]]
name = "tempfile"
-version = "3.11.0"
+version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
- "cfg-if",
"fastrand",
+ "getrandom 0.3.2",
"once_cell",
"rustix",
- "windows-sys",
+ "windows-sys 0.59.0",
]
[[package]]
name = "tokio"
-version = "1.39.2"
+version = "1.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
+checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
dependencies = [
"backtrace",
"bytes",
@@ -340,14 +331,14 @@
"signal-hook-registry",
"socket2",
"tokio-macros",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
@@ -356,9 +347,9 @@
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "wasi"
@@ -374,32 +365,32 @@
[[package]]
name = "wasi"
-version = "0.13.3+wasi-0.2.2"
+version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
-version = "0.2.92"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
+ "once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.92"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
- "once_cell",
"proc-macro2",
"quote",
"syn",
@@ -408,9 +399,9 @@
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.92"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -418,9 +409,9 @@
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.92"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
@@ -431,9 +422,12 @@
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.92"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
[[package]]
name = "winapi"
@@ -467,6 +461,15 @@
]
[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -532,9 +535,9 @@
[[package]]
name = "wit-bindgen-rt"
-version = "0.33.0"
+version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
diff --git a/src/tools/miri/test_dependencies/Cargo.toml b/src/tools/miri/test_dependencies/Cargo.toml
index 78dddaf..653228a 100644
--- a/src/tools/miri/test_dependencies/Cargo.toml
+++ b/src/tools/miri/test_dependencies/Cargo.toml
@@ -22,9 +22,9 @@
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.24", features = ["macros", "rt-multi-thread", "time", "net", "fs", "sync", "signal", "io-util"] }
+tokio = { version = "1", features = ["macros", "rt-multi-thread", "time", "net", "fs", "sync", "signal", "io-util"] }
[target.'cfg(windows)'.dependencies]
-windows-sys = { version = "0.52", features = [ "Win32_Foundation", "Win32_System_Threading" ] }
+windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_System_Threading", "Win32_Storage_FileSystem", "Win32_Security"] }
[workspace]
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
index 279201d..3ee2bf1 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
@@ -13,7 +13,7 @@
// XXX HACK: This is how miri represents the handle for thread 0.
// This value can be "legitimately" obtained by using `GetCurrentThread` with `DuplicateHandle`
// but miri does not implement `DuplicateHandle` yet.
-const MAIN_THREAD: HANDLE = (2i32 << 30) as HANDLE;
+const MAIN_THREAD: HANDLE = (2i32 << 29) as HANDLE;
fn main() {
thread::spawn(|| {
diff --git a/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs
new file mode 100644
index 0000000..38a0bf5
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs
@@ -0,0 +1,260 @@
+//@only-target: freebsd
+//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-isolation
+
+use std::mem::{self, MaybeUninit};
+use std::ptr::{self, addr_of};
+use std::sync::atomic::AtomicU32;
+use std::time::Instant;
+use std::{io, thread};
+
+fn wait_wake() {
+ fn wake_nobody() {
+ // Current thread waits on futex.
+ // New thread wakes up 0 threads waiting on that futex.
+ // Current thread should time out.
+ static mut FUTEX: u32 = 0;
+
+ let waker = thread::spawn(|| {
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ addr_of!(FUTEX) as *mut _,
+ libc::UMTX_OP_WAKE_PRIVATE,
+ 0, // wake up 0 waiters
+ ptr::null_mut::<libc::c_void>(),
+ ptr::null_mut::<libc::c_void>(),
+ ),
+ 0
+ );
+ }
+ });
+
+ // 10ms should be enough.
+ let mut timeout = libc::timespec { tv_sec: 0, tv_nsec: 10_000_000 };
+ let timeout_size_arg =
+ ptr::without_provenance_mut::<libc::c_void>(mem::size_of::<libc::timespec>());
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ addr_of!(FUTEX) as *mut _,
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 0,
+ timeout_size_arg,
+ &mut timeout as *mut _ as _,
+ ),
+ -1
+ );
+ // Main thread did not get woken up, so it timed out.
+ assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+ }
+
+ waker.join().unwrap();
+ }
+
+ fn wake_two_of_three() {
+ // We create 2 threads that wait on a futex with a 100ms timeout.
+ // The main thread wakes up 2 threads waiting on this futex and after this
+ // checks that only those threads woke up and the other one timed out.
+ static mut FUTEX: u32 = 0;
+
+ fn waiter() -> bool {
+ let mut timeout = libc::timespec { tv_sec: 0, tv_nsec: 100_000_000 };
+ let timeout_size_arg =
+ ptr::without_provenance_mut::<libc::c_void>(mem::size_of::<libc::timespec>());
+ unsafe {
+ libc::_umtx_op(
+ addr_of!(FUTEX) as *mut _,
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 0, // FUTEX is 0
+ timeout_size_arg,
+ &mut timeout as *mut _ as _,
+ );
+ // Return true if this thread woke up.
+ io::Error::last_os_error().raw_os_error().unwrap() != libc::ETIMEDOUT
+ }
+ }
+
+ let t1 = thread::spawn(waiter);
+ let t2 = thread::spawn(waiter);
+ let t3 = thread::spawn(waiter);
+
+ // Run all the waiters, so they can go to sleep.
+ thread::yield_now();
+
+ // Wake up 2 thread and make sure 1 is still waiting.
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ addr_of!(FUTEX) as *mut _,
+ libc::UMTX_OP_WAKE_PRIVATE,
+ 2,
+ ptr::null_mut::<libc::c_void>(),
+ ptr::null_mut::<libc::c_void>(),
+ ),
+ 0
+ );
+ }
+
+ // Treat the booleans as numbers to simplify checking how many threads were woken up.
+ let t1 = t1.join().unwrap() as usize;
+ let t2 = t2.join().unwrap() as usize;
+ let t3 = t3.join().unwrap() as usize;
+ let woken_up_count = t1 + t2 + t3;
+ assert!(woken_up_count == 2, "Expected 2 threads to wake up got: {woken_up_count}");
+ }
+
+ wake_nobody();
+ wake_two_of_three();
+}
+
+fn wake_dangling() {
+ let futex = Box::new(0);
+ let ptr: *const u32 = &*futex;
+ drop(futex);
+
+ // Expect error since this is now "unmapped" memory.
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ ptr as *const AtomicU32 as *mut _,
+ libc::UMTX_OP_WAKE_PRIVATE,
+ 0,
+ ptr::null_mut::<libc::c_void>(),
+ ptr::null_mut::<libc::c_void>(),
+ ),
+ -1
+ );
+ assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EFAULT);
+ }
+}
+
+fn wait_wrong_val() {
+ let futex: u32 = 123;
+
+ // Wait with a wrong value just returns 0
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ ptr::from_ref(&futex).cast_mut().cast(),
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 456,
+ ptr::null_mut::<libc::c_void>(),
+ ptr::null_mut::<libc::c_void>(),
+ ),
+ 0
+ );
+ }
+}
+
+fn wait_relative_timeout() {
+ fn without_timespec() {
+ let start = Instant::now();
+
+ let futex: u32 = 123;
+
+ let mut timeout = libc::timespec { tv_sec: 0, tv_nsec: 200_000_000 };
+ let timeout_size_arg =
+ ptr::without_provenance_mut::<libc::c_void>(mem::size_of::<libc::timespec>());
+ // Wait for 200ms, with nobody waking us up early
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ ptr::from_ref(&futex).cast_mut().cast(),
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 123,
+ timeout_size_arg,
+ &mut timeout as *mut _ as _,
+ ),
+ -1
+ );
+ assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+ }
+
+ assert!((200..1000).contains(&start.elapsed().as_millis()));
+ }
+
+ fn with_timespec() {
+ let futex: u32 = 123;
+ let mut timeout = libc::_umtx_time {
+ _timeout: libc::timespec { tv_sec: 0, tv_nsec: 200_000_000 },
+ _flags: 0,
+ _clockid: libc::CLOCK_MONOTONIC as u32,
+ };
+ let timeout_size_arg =
+ ptr::without_provenance_mut::<libc::c_void>(mem::size_of::<libc::_umtx_time>());
+
+ let start = Instant::now();
+
+ // Wait for 200ms, with nobody waking us up early
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ ptr::from_ref(&futex).cast_mut().cast(),
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 123,
+ timeout_size_arg,
+ &mut timeout as *mut _ as _,
+ ),
+ -1
+ );
+ assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+ }
+ assert!((200..1000).contains(&start.elapsed().as_millis()));
+ }
+
+ without_timespec();
+ with_timespec();
+}
+
+fn wait_absolute_timeout() {
+ let start = Instant::now();
+
+ // Get the current monotonic timestamp as timespec.
+ let mut timeout = unsafe {
+ let mut now: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
+ assert_eq!(libc::clock_gettime(libc::CLOCK_MONOTONIC, now.as_mut_ptr()), 0);
+ now.assume_init()
+ };
+
+ // Add 200ms.
+ timeout.tv_nsec += 200_000_000;
+ if timeout.tv_nsec > 1_000_000_000 {
+ timeout.tv_nsec -= 1_000_000_000;
+ timeout.tv_sec += 1;
+ }
+
+ // Create umtx_timeout struct with that absolute timeout.
+ let umtx_timeout = libc::_umtx_time {
+ _timeout: timeout,
+ _flags: libc::UMTX_ABSTIME,
+ _clockid: libc::CLOCK_MONOTONIC as u32,
+ };
+ let umtx_timeout_ptr = &umtx_timeout as *const _;
+ let umtx_timeout_size = ptr::without_provenance_mut(mem::size_of_val(&umtx_timeout));
+
+ let futex: u32 = 123;
+
+ // Wait for 200ms from now, with nobody waking us up early.
+ unsafe {
+ assert_eq!(
+ libc::_umtx_op(
+ ptr::from_ref(&futex).cast_mut().cast(),
+ libc::UMTX_OP_WAIT_UINT_PRIVATE,
+ 123,
+ umtx_timeout_size,
+ umtx_timeout_ptr as *mut _,
+ ),
+ -1
+ );
+ assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+ }
+ assert!((200..1000).contains(&start.elapsed().as_millis()));
+}
+
+fn main() {
+ wait_wake();
+ wake_dangling();
+ wait_wrong_val();
+ wait_relative_timeout();
+ wait_absolute_timeout();
+}
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
index ce829ee..2796541 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
@@ -9,6 +9,10 @@
use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0};
use windows_sys::Win32::System::Threading::{INFINITE, WaitForSingleObject};
+#[derive(Copy, Clone)]
+struct UnsafeSendWrapper<T>(T);
+unsafe impl<T> Send for UnsafeSendWrapper<T> {}
+
fn main() {
static FLAG: AtomicBool = AtomicBool::new(false);
@@ -17,10 +21,12 @@ fn main() {
thread::yield_now();
}
})
- .into_raw_handle() as HANDLE;
+ .into_raw_handle();
+ let blocker = UnsafeSendWrapper(blocker as HANDLE);
let waiter = move || unsafe {
- assert_eq!(WaitForSingleObject(blocker, INFINITE), WAIT_OBJECT_0);
+ let blocker = blocker; // circumvent per-field capturing
+ assert_eq!(WaitForSingleObject(blocker.0, INFINITE), WAIT_OBJECT_0);
};
let waiter1 = thread::spawn(waiter);
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs
index 99d6d2b..116cde4 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs
@@ -1,4 +1,5 @@
//@ignore-target: windows # File handling is not implemented yet
+//@ignore-target: solaris # Does not have flock
//@compile-flags: -Zmiri-disable-isolation
use std::fs::File;
diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
new file mode 100644
index 0000000..312df9e
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -0,0 +1,198 @@
+//@only-target: windows # this directly tests windows-only functions
+//@compile-flags: -Zmiri-disable-isolation
+#![allow(nonstandard_style)]
+
+use std::os::windows::ffi::OsStrExt;
+use std::path::Path;
+use std::ptr;
+
+#[path = "../../utils/mod.rs"]
+mod utils;
+
+use windows_sys::Win32::Foundation::{
+ CloseHandle, ERROR_ALREADY_EXISTS, GENERIC_READ, GENERIC_WRITE, GetLastError,
+};
+use windows_sys::Win32::Storage::FileSystem::{
+ BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
+ FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT,
+ FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS,
+ OPEN_EXISTING,
+};
+
+fn main() {
+ unsafe {
+ test_create_dir_file();
+ test_create_normal_file();
+ test_create_always_twice();
+ test_open_always_twice();
+ test_open_dir_reparse();
+ }
+}
+
+unsafe fn test_create_dir_file() {
+ let temp = utils::tmp();
+ let raw_path = to_wide_cstr(&temp);
+ // Open the `temp` directory.
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ let mut info = std::mem::zeroed::<BY_HANDLE_FILE_INFORMATION>();
+ if GetFileInformationByHandle(handle, &mut info) == 0 {
+ panic!("Failed to get file information")
+ };
+ assert!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+}
+
+unsafe fn test_create_normal_file() {
+ let temp = utils::tmp().join("test.txt");
+ let raw_path = to_wide_cstr(&temp);
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ CREATE_NEW,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ let mut info = std::mem::zeroed::<BY_HANDLE_FILE_INFORMATION>();
+ if GetFileInformationByHandle(handle, &mut info) == 0 {
+ panic!("Failed to get file information: {}", GetLastError())
+ };
+ assert!(info.dwFileAttributes & FILE_ATTRIBUTE_NORMAL != 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+
+ // Test metadata-only handle
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ OPEN_EXISTING,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ let mut info = std::mem::zeroed::<BY_HANDLE_FILE_INFORMATION>();
+ if GetFileInformationByHandle(handle, &mut info) == 0 {
+ panic!("Failed to get file information: {}", GetLastError())
+ };
+ assert!(info.dwFileAttributes & FILE_ATTRIBUTE_NORMAL != 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+}
+
+/// Tests that CREATE_ALWAYS sets the error value correctly based on whether the file already exists
+unsafe fn test_create_always_twice() {
+ let temp = utils::tmp().join("test_create_always.txt");
+ let raw_path = to_wide_cstr(&temp);
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ CREATE_ALWAYS,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ assert_eq!(GetLastError(), 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ CREATE_ALWAYS,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ assert_eq!(GetLastError(), ERROR_ALREADY_EXISTS);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+}
+
+/// Tests that OPEN_ALWAYS sets the error value correctly based on whether the file already exists
+unsafe fn test_open_always_twice() {
+ let temp = utils::tmp().join("test_open_always.txt");
+ let raw_path = to_wide_cstr(&temp);
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ OPEN_ALWAYS,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ assert_eq!(GetLastError(), 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ OPEN_ALWAYS,
+ 0,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ assert_eq!(GetLastError(), ERROR_ALREADY_EXISTS);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+}
+
+// TODO: Once we support more of the std API, it would be nice to test against an actual symlink
+unsafe fn test_open_dir_reparse() {
+ let temp = utils::tmp();
+ let raw_path = to_wide_cstr(&temp);
+ // Open the `temp` directory.
+ let handle = CreateFileW(
+ raw_path.as_ptr(),
+ GENERIC_READ,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ ptr::null_mut(),
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
+ ptr::null_mut(),
+ );
+ assert_ne!(handle.addr(), usize::MAX, "CreateFileW Failed: {}", GetLastError());
+ let mut info = std::mem::zeroed::<BY_HANDLE_FILE_INFORMATION>();
+ if GetFileInformationByHandle(handle, &mut info) == 0 {
+ panic!("Failed to get file information")
+ };
+ assert!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0);
+ if CloseHandle(handle) == 0 {
+ panic!("Failed to close file")
+ };
+}
+
+fn to_wide_cstr(path: &Path) -> Vec<u16> {
+ let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>();
+ raw_path.extend([0, 0]);
+ raw_path
+}
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 05ac5e8..cd60b6b 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -38,8 +38,9 @@ macro_rules! assert_approx_eq {
}};
($a:expr, $b: expr) => {
- // accept up to 64ULP (16ULP for host floats and 16ULP for miri artificial error and 32 for any rounding errors)
- assert_approx_eq!($a, $b, 64);
+ // accept up to 12ULP (4ULP for host floats and 4ULP for miri artificial error and 4 for any additional effects
+ // due to having multiple error sources.
+ assert_approx_eq!($a, $b, 12);
};
}
diff --git a/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs b/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs
new file mode 100644
index 0000000..a1da60c
--- /dev/null
+++ b/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs
@@ -0,0 +1,30 @@
+use std::mem::{size_of, align_of};
+
+// See <https://github.com/rust-lang/rust/issues/134713>
+
+#[repr(C)]
+struct Foo(usize, u8);
+
+fn main() {
+ let buf1: [usize; 2] = [1000, 2000];
+ let buf2: [usize; 2] = [3000, 4000];
+
+ // Foo and [usize; 2] have the same size and alignment,
+ // so swap_nonoverlapping should treat them the same
+ assert_eq!(size_of::<Foo>(), size_of::<[usize; 2]>());
+ assert_eq!(align_of::<Foo>(), align_of::<[usize; 2]>());
+
+ let mut b1 = buf1;
+ let mut b2 = buf2;
+ // Safety: b1 and b2 are distinct local variables,
+ // with the same size and alignment as Foo.
+ unsafe {
+ std::ptr::swap_nonoverlapping(
+ b1.as_mut_ptr().cast::<Foo>(),
+ b2.as_mut_ptr().cast::<Foo>(),
+ 1,
+ );
+ }
+ assert_eq!(b1, buf2);
+ assert_eq!(b2, buf1);
+}
diff --git a/src/tools/miri/tests/pass/path.rs b/src/tools/miri/tests/pass/path.rs
index 299ee6c..7428d0af 100644
--- a/src/tools/miri/tests/pass/path.rs
+++ b/src/tools/miri/tests/pass/path.rs
@@ -6,7 +6,11 @@
#[track_caller]
fn assert_absolute_eq(in_: &str, out: &str) {
- assert_eq!(absolute(in_).unwrap().as_os_str(), Path::new(out).as_os_str());
+ assert_eq!(
+ absolute(in_).unwrap().as_os_str(),
+ Path::new(out).as_os_str(),
+ "incorrect absolute path for {in_:?}"
+ );
}
fn test_absolute() {
@@ -29,11 +33,28 @@ fn test_absolute() {
assert_absolute_eq(r"\\?\C:\path\to\file", r"\\?\C:\path\to\file");
assert_absolute_eq(r"\\?\UNC\server\share\to\file", r"\\?\UNC\server\share\to\file");
assert_absolute_eq(r"\\?\PIPE\name", r"\\?\PIPE\name");
+ assert_absolute_eq(r"\\server\share\NUL", r"\\server\share\NUL");
+ // This fails on Windows 10 hosts. FIXME: enable this once GHA runners are on Windows 11.
+ //assert_absolute_eq(r"C:\path\to\COM1", r"C:\path\to\COM1");
// Verbatim paths are always unchanged, no matter what.
assert_absolute_eq(r"\\?\path.\to/file..", r"\\?\path.\to/file..");
-
+ // Trailing dot is removed here.
assert_absolute_eq(r"C:\path..\to.\file.", r"C:\path..\to\file");
+ // `..` is resolved here.
+ assert_absolute_eq(r"C:\path\to\..\file", r"C:\path\file");
+ assert_absolute_eq(r"C:\path\to\..\..\file", r"C:\file");
+ assert_absolute_eq(r"C:\path\to\..\..\..\..\..\..\file", r"C:\file");
+ assert_absolute_eq(r"C:\..", r"C:\");
+ assert_absolute_eq(r"\\server\share\to\path\with\..\file", r"\\server\share\to\path\file");
+ assert_absolute_eq(r"\\server\share\to\..\..\..\..\file", r"\\server\share\file");
+ assert_absolute_eq(r"\\server\share\..", r"\\server\share");
+ // Magic filenames.
+ assert_absolute_eq(r"NUL", r"\\.\NUL");
+ assert_absolute_eq(r"nul", r"\\.\nul");
assert_absolute_eq(r"COM1", r"\\.\COM1");
+ assert_absolute_eq(r"com1", r"\\.\com1");
+ assert_absolute_eq(r"C:\path\to\NUL", r"\\.\NUL");
+ assert_absolute_eq(r"C:\path\to\nul", r"\\.\nul");
} else {
panic!("unsupported OS");
}
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 289c6aa..6ad2305 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -1,4 +1,3 @@
-//@ignore-target: windows # File handling is not implemented yet
//@compile-flags: -Zmiri-disable-isolation
#![feature(io_error_more)]
@@ -18,20 +17,23 @@
fn main() {
test_path_conversion();
- test_file();
- test_file_clone();
- test_file_create_new();
- test_seek();
- test_metadata();
- test_file_set_len();
- test_file_sync();
- test_errors();
- test_rename();
- test_directory();
- test_canonicalize();
- test_from_raw_os_error();
- #[cfg(unix)]
- test_pread_pwrite();
+ // Windows file handling is very incomplete.
+ if cfg!(not(windows)) {
+ test_file();
+ test_file_create_new();
+ test_seek();
+ test_file_clone();
+ test_metadata();
+ test_file_set_len();
+ test_file_sync();
+ test_errors();
+ test_rename();
+ test_directory();
+ test_canonicalize();
+ test_from_raw_os_error();
+ #[cfg(unix)]
+ test_pread_pwrite();
+ }
}
fn test_path_conversion() {
@@ -144,10 +146,10 @@ fn test_metadata() {
let path = utils::prepare_with_content("miri_test_fs_metadata.txt", bytes);
// Test that metadata of an absolute path is correct.
- check_metadata(bytes, &path).unwrap();
+ check_metadata(bytes, &path).expect("absolute path metadata");
// Test that metadata of a relative path is correct.
std::env::set_current_dir(path.parent().unwrap()).unwrap();
- check_metadata(bytes, Path::new(path.file_name().unwrap())).unwrap();
+ check_metadata(bytes, Path::new(path.file_name().unwrap())).expect("relative path metadata");
// Removing file should succeed.
remove_file(&path).unwrap();
diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml
index 4e01376..60e80c3 100644
--- a/src/tools/miri/triagebot.toml
+++ b/src/tools/miri/triagebot.toml
@@ -40,3 +40,9 @@
# Automatically close and reopen PRs made by bots to run CI on them
[bot-pull-requests]
+
+# Canonicalize issue numbers to avoid closing the wrong issue when upstreaming this subtree
+[canonicalize-issue-links]
+
+# Prevents mentions in commits to avoid users being spammed
+[no-mentions]
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 1a57d2b..bf3b411 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -361,7 +361,6 @@
"rustc-demangle",
"rustc-hash",
"rustc-literal-escaper",
- "rustc-rayon",
"rustc-rayon-core",
"rustc-stable-hash",
"rustc_apfloat",
diff --git a/tests/assembly/cstring-merging.rs b/tests/assembly/cstring-merging.rs
index 7436e24..07f25d1 100644
--- a/tests/assembly/cstring-merging.rs
+++ b/tests/assembly/cstring-merging.rs
@@ -1,6 +1,7 @@
//@ only-linux
//@ assembly-output: emit-asm
-//@ compile-flags: --crate-type=lib -Copt-level=3 --edition 2024
+//@ compile-flags: --crate-type=lib -Copt-level=3
+//@ edition: 2024
use std::ffi::CStr;
diff --git a/tests/assembly/x86_64-typed-swap.rs b/tests/assembly/x86_64-typed-swap.rs
index dfd6ee5..a675301 100644
--- a/tests/assembly/x86_64-typed-swap.rs
+++ b/tests/assembly/x86_64-typed-swap.rs
@@ -51,3 +51,31 @@ pub fn swap_simd(x: &mut __m128, y: &mut __m128) {
// CHECK-NEXT: retq
swap(x, y)
}
+
+// CHECK-LABEL: swap_string:
+#[no_mangle]
+pub fn swap_string(x: &mut String, y: &mut String) {
+ // CHECK-NOT: mov
+ // CHECK-COUNT-4: movups
+ // CHECK-NOT: mov
+ // CHECK-COUNT-4: movq
+ // CHECK-NOT: mov
+ swap(x, y)
+}
+
+// CHECK-LABEL: swap_44_bytes:
+#[no_mangle]
+pub fn swap_44_bytes(x: &mut [u8; 44], y: &mut [u8; 44]) {
+ // Ensure we do better than a long run of byte copies,
+ // see <https://github.com/rust-lang/rust/issues/134946>
+
+ // CHECK-NOT: movb
+ // CHECK-COUNT-8: movups{{.+}}xmm
+ // CHECK-NOT: movb
+ // CHECK-COUNT-4: movq
+ // CHECK-NOT: movb
+ // CHECK-COUNT-4: movl
+ // CHECK-NOT: movb
+ // CHECK: retq
+ swap(x, y)
+}
diff --git a/tests/assembly/x86_64-windows-float-abi.rs b/tests/assembly/x86_64-windows-float-abi.rs
index e8900be..cbc8091 100644
--- a/tests/assembly/x86_64-windows-float-abi.rs
+++ b/tests/assembly/x86_64-windows-float-abi.rs
@@ -37,7 +37,8 @@ pub extern "C" fn second_f64(_: f64, x: f64) -> f64 {
}
// CHECK-LABEL: second_f128
-// CHECK: movaps %xmm1, %xmm0
+// FIXME(llvm21): this can be just %rdx instead of the regex once we don't test on LLVM 20
+// CHECK: movaps {{(%xmm1|\(%rdx\))}}, %xmm0
// CHECK-NEXT: retq
#[no_mangle]
pub extern "C" fn second_f128(_: f128, x: f128) -> f128 {
diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs
index 2d67e02..b5b369e 100644
--- a/tests/codegen/async-closure-debug.rs
+++ b/tests/codegen/async-closure-debug.rs
@@ -1,6 +1,7 @@
// Just make sure that async closures don't ICE.
//
-//@ compile-flags: -C debuginfo=2 --edition=2018
+//@ compile-flags: -C debuginfo=2
+//@ edition: 2018
//@ ignore-msvc
// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "async_closure_test"
diff --git a/tests/codegen/async-fn-debug-awaitee-field.rs b/tests/codegen/async-fn-debug-awaitee-field.rs
index ab13d45..50860c9 100644
--- a/tests/codegen/async-fn-debug-awaitee-field.rs
+++ b/tests/codegen/async-fn-debug-awaitee-field.rs
@@ -7,7 +7,8 @@
//@[MSVC] only-msvc
//@[NONMSVC] ignore-msvc
-//@ compile-flags: -C debuginfo=2 --edition=2018 -Copt-level=0
+//@ compile-flags: -C debuginfo=2 -Copt-level=0
+//@ edition: 2018
#![crate_type = "lib"]
diff --git a/tests/codegen/async-fn-debug-msvc.rs b/tests/codegen/async-fn-debug-msvc.rs
index 7c69504..e0c6011 100644
--- a/tests/codegen/async-fn-debug-msvc.rs
+++ b/tests/codegen/async-fn-debug-msvc.rs
@@ -4,7 +4,8 @@
// - Other fields are not marked artificial
//
//
-//@ compile-flags: -C debuginfo=2 --edition=2018
+//@ compile-flags: -C debuginfo=2
+//@ edition: 2018
//@ only-msvc
async fn foo() {}
@@ -19,23 +20,23 @@ async fn async_fn_test() {
// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
-// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
+// CHECK-SAME: file: [[FILE:![0-9]*]], line: 12,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant1", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 15,
+// CHECK-SAME: file: [[FILE]], line: 16,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant2", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 15,
+// CHECK-SAME: file: [[FILE]], line: 16,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant3", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 12,
+// CHECK-SAME: file: [[FILE]], line: 13,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
diff --git a/tests/codegen/async-fn-debug.rs b/tests/codegen/async-fn-debug.rs
index 7be4ad4..ed704c7 100644
--- a/tests/codegen/async-fn-debug.rs
+++ b/tests/codegen/async-fn-debug.rs
@@ -4,7 +4,8 @@
// - Other fields are not marked artificial
//
//
-//@ compile-flags: -C debuginfo=2 --edition=2018
+//@ compile-flags: -C debuginfo=2
+//@ edition: 2018
//@ ignore-msvc
async fn foo() {}
@@ -22,26 +23,26 @@ async fn async_fn_test() {
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
+// CHECK-SAME: file: [[FILE:![0-9]*]], line: 12,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 15,
+// CHECK-SAME: file: [[FILE]], line: 16,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 15,
+// CHECK-SAME: file: [[FILE]], line: 16,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 12,
+// CHECK-SAME: file: [[FILE]], line: 13,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 15,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
diff --git a/tests/codegen/coroutine-debug.rs b/tests/codegen/coroutine-debug.rs
index d00667a..ff62e97 100644
--- a/tests/codegen/coroutine-debug.rs
+++ b/tests/codegen/coroutine-debug.rs
@@ -4,7 +4,8 @@
// - Other fields are not marked artificial
//
//
-//@ compile-flags: -C debuginfo=2 --edition=2018
+//@ compile-flags: -C debuginfo=2
+//@ edition: 2018
//@ ignore-msvc
#![feature(coroutines, coroutine_trait)]
@@ -27,26 +28,26 @@ fn coroutine_test() -> impl Coroutine<Yield = i32, Return = ()> {
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: discriminator: [[DISC:![0-9]*]]
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE:![0-9]*]], line: 15,
+// CHECK-SAME: file: [[FILE:![0-9]*]], line: 16,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 19,
+// CHECK-SAME: file: [[FILE]], line: 20,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 19,
+// CHECK-SAME: file: [[FILE]], line: 20,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 16,
+// CHECK-SAME: file: [[FILE]], line: 17,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 18,
+// CHECK-SAME: file: [[FILE]], line: 19,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
diff --git a/tests/codegen/debuginfo-generic-closure-env-names.rs b/tests/codegen/debuginfo-generic-closure-env-names.rs
index 6b314c9..64bc58e 100644
--- a/tests/codegen/debuginfo-generic-closure-env-names.rs
+++ b/tests/codegen/debuginfo-generic-closure-env-names.rs
@@ -18,7 +18,8 @@
// legacy mangling scheme rustc version and generic parameters are both hashed into a single part
// of the name, thus randomizing item order with respect to rustc version.
-//@ compile-flags: -Cdebuginfo=2 --edition 2021 -Copt-level=0 -Csymbol-mangling-version=v0
+//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 -Csymbol-mangling-version=v0
+//@ edition: 2021
// non_generic_closure()
// NONMSVC: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: ![[non_generic_closure_NAMESPACE:[0-9]+]],
diff --git a/tests/codegen/ergonomic-clones/closure.rs b/tests/codegen/ergonomic-clones/closure.rs
new file mode 100644
index 0000000..b6fc817
--- /dev/null
+++ b/tests/codegen/ergonomic-clones/closure.rs
@@ -0,0 +1,55 @@
+//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmir-opt-level=0
+
+#![crate_type = "lib"]
+
+#![feature(ergonomic_clones)]
+#![allow(incomplete_features)]
+
+use std::clone::UseCloned;
+
+pub fn ergonomic_clone_closure_move() -> String {
+ let s = String::from("hi");
+
+ // CHECK-NOT: ; call core::clone::impls::<impl core::clone::Clone for String>::clone
+ let cl = use || s;
+ cl()
+}
+
+#[derive(Clone)]
+struct Foo;
+
+impl UseCloned for Foo {}
+
+pub fn ergonomic_clone_closure_use_cloned() -> Foo {
+ let f = Foo;
+
+ // CHECK: ; call <closure::Foo as core::clone::Clone>::clone
+ let f1 = use || f;
+
+ // CHECK: ; call <closure::Foo as core::clone::Clone>::clone
+ let f2 = use || f;
+
+ f
+}
+
+pub fn ergonomic_clone_closure_copy() -> i32 {
+ let i = 1;
+
+ // CHECK-NOT: ; call core::clone::impls::<impl core::clone::Clone for i32>::clone
+ let i1 = use || i;
+
+ // CHECK-NOT: ; call core::clone::impls::<impl core::clone::Clone for i32>::clone
+ let i2 = use || i;
+
+ i
+}
+
+pub fn ergonomic_clone_closure_use_cloned_generics<T: UseCloned>(f: T) -> T {
+ // CHECK-NOT: ; call core::clone::impls::<impl core::clone::Clone for i32>::clone
+ let f1 = use || f;
+
+ // CHECK-NOT: ; call core::clone::impls::<impl core::clone::Clone for i32>::clone
+ let f2 = use || f;
+
+ f
+}
diff --git a/tests/codegen/infallible-unwrap-in-opt-z.rs b/tests/codegen/infallible-unwrap-in-opt-z.rs
index 3756faf..c2297c5 100644
--- a/tests/codegen/infallible-unwrap-in-opt-z.rs
+++ b/tests/codegen/infallible-unwrap-in-opt-z.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: -C opt-level=z --edition=2021
+//@ compile-flags: -C opt-level=z
+//@ edition: 2021
#![crate_type = "lib"]
diff --git a/tests/codegen/inline-function-args-debug-info.rs b/tests/codegen/inline-function-args-debug-info.rs
index 53a1791..c31419c 100644
--- a/tests/codegen/inline-function-args-debug-info.rs
+++ b/tests/codegen/inline-function-args-debug-info.rs
@@ -2,7 +2,8 @@
// gets inlined by MIR inlining. Without function argument indexes, `info args` in gdb won't show
// arguments and their values for the current function.
-//@ compile-flags: -Zinline-mir=yes -Cdebuginfo=2 --edition=2021
+//@ compile-flags: -Zinline-mir=yes -Cdebuginfo=2
+//@ edition: 2021
#![crate_type = "lib"]
@@ -14,9 +15,9 @@ pub fn outer_function(x: usize, y: usize) -> usize {
#[inline]
fn inner_function(aaaa: usize, bbbb: usize) -> usize {
// CHECK: !DILocalVariable(name: "aaaa", arg: 1
- // CHECK-SAME: line: 15
+ // CHECK-SAME: line: 16
// CHECK-NOT: !DILexicalBlock(
// CHECK: !DILocalVariable(name: "bbbb", arg: 2
- // CHECK-SAME: line: 15
+ // CHECK-SAME: line: 16
aaaa + bbbb
}
diff --git a/tests/codegen/issues/issue-119422.rs b/tests/codegen/issues/issue-119422.rs
index e1a082c..17ae716 100644
--- a/tests/codegen/issues/issue-119422.rs
+++ b/tests/codegen/issues/issue-119422.rs
@@ -1,7 +1,8 @@
//! This test checks that compiler don't generate useless compares to zeros
//! for `NonZero` integer types.
//!
-//@ compile-flags: -Copt-level=3 --edition=2021 -Zmerge-functions=disabled
+//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
+//@ edition: 2021
//@ only-64bit (because the LLVM type of i64 for usize shows up)
#![crate_type = "lib"]
diff --git a/tests/codegen/simd/extract-insert-dyn.rs b/tests/codegen/simd/extract-insert-dyn.rs
new file mode 100644
index 0000000..584e2c7
--- /dev/null
+++ b/tests/codegen/simd/extract-insert-dyn.rs
@@ -0,0 +1,75 @@
+//@compile-flags: -C opt-level=3 -C no-prepopulate-passes
+
+#![feature(core_intrinsics, repr_simd)]
+#![no_std]
+#![crate_type = "lib"]
+#![allow(non_camel_case_types)]
+
+// Test that `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`
+// lower to an LLVM extractelement or insertelement operation.
+
+use core::intrinsics::simd::{simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn};
+
+#[repr(simd)]
+#[derive(Clone, Copy)]
+pub struct u32x16([u32; 16]);
+
+#[repr(simd)]
+#[derive(Clone, Copy)]
+pub struct i8x16([i8; 16]);
+
+// CHECK-LABEL: dyn_simd_extract
+// CHECK: extractelement <16 x i8> %x, i32 %idx
+#[no_mangle]
+unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
+ simd_extract_dyn(x, idx)
+}
+
+// CHECK-LABEL: literal_dyn_simd_extract
+// CHECK: extractelement <16 x i8> %x, i32 7
+#[no_mangle]
+unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
+ simd_extract_dyn(x, 7)
+}
+
+// CHECK-LABEL: const_dyn_simd_extract
+// CHECK: extractelement <16 x i8> %x, i32 7
+#[no_mangle]
+unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
+ simd_extract_dyn(x, const { 3 + 4 })
+}
+
+// CHECK-LABEL: const_simd_extract
+// CHECK: extractelement <16 x i8> %x, i32 7
+#[no_mangle]
+unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
+ simd_extract(x, const { 3 + 4 })
+}
+
+// CHECK-LABEL: dyn_simd_insert
+// CHECK: insertelement <16 x i8> %x, i8 %e, i32 %idx
+#[no_mangle]
+unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
+ simd_insert_dyn(x, idx, e)
+}
+
+// CHECK-LABEL: literal_dyn_simd_insert
+// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+#[no_mangle]
+unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
+ simd_insert_dyn(x, 7, e)
+}
+
+// CHECK-LABEL: const_dyn_simd_insert
+// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+#[no_mangle]
+unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
+ simd_insert_dyn(x, const { 3 + 4 }, e)
+}
+
+// CHECK-LABEL: const_simd_insert
+// CHECK: insertelement <16 x i8> %x, i8 %e, i32 7
+#[no_mangle]
+unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
+ simd_insert(x, const { 3 + 4 }, e)
+}
diff --git a/tests/codegen/simd/simd-wide-sum.rs b/tests/codegen/simd/simd-wide-sum.rs
index fb9b618..95117b2 100644
--- a/tests/codegen/simd/simd-wide-sum.rs
+++ b/tests/codegen/simd/simd-wide-sum.rs
@@ -1,5 +1,6 @@
//@ revisions: llvm mir-opt3
-//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled --edition=2021
+//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
+//@ edition: 2021
//@ only-x86_64
//@ [mir-opt3]compile-flags: -Zmir-opt-level=3
//@ [mir-opt3]build-pass
diff --git a/tests/codegen/simd/swap-simd-types.rs b/tests/codegen/simd/swap-simd-types.rs
index 69767d0..c063cc6 100644
--- a/tests/codegen/simd/swap-simd-types.rs
+++ b/tests/codegen/simd/swap-simd-types.rs
@@ -23,8 +23,8 @@ pub fn swap_single_m256(x: &mut __m256, y: &mut __m256) {
#[no_mangle]
pub fn swap_m256_slice(x: &mut [__m256], y: &mut [__m256]) {
// CHECK-NOT: alloca
- // CHECK: load <8 x float>{{.+}}align 32
- // CHECK: store <8 x float>{{.+}}align 32
+ // CHECK-COUNT-2: load <4 x i64>{{.+}}align 32
+ // CHECK-COUNT-2: store <4 x i64>{{.+}}align 32
if x.len() == y.len() {
x.swap_with_slice(y);
}
@@ -34,7 +34,7 @@ pub fn swap_m256_slice(x: &mut [__m256], y: &mut [__m256]) {
#[no_mangle]
pub fn swap_bytes32(x: &mut [u8; 32], y: &mut [u8; 32]) {
// CHECK-NOT: alloca
- // CHECK: load <32 x i8>{{.+}}align 1
- // CHECK: store <32 x i8>{{.+}}align 1
+ // CHECK-COUNT-2: load <4 x i64>{{.+}}align 1
+ // CHECK-COUNT-2: store <4 x i64>{{.+}}align 1
swap(x, y)
}
diff --git a/tests/codegen/string-push.rs b/tests/codegen/string-push.rs
new file mode 100644
index 0000000..cf5f6bb
--- /dev/null
+++ b/tests/codegen/string-push.rs
@@ -0,0 +1,11 @@
+//! Check that `String::push` is optimized enough not to call `memcpy`.
+
+//@ compile-flags: -O
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @string_push_does_not_call_memcpy
+#[no_mangle]
+pub fn string_push_does_not_call_memcpy(s: &mut String, ch: char) {
+ // CHECK-NOT: call void @llvm.memcpy
+ s.push(ch);
+}
diff --git a/tests/codegen/swap-large-types.rs b/tests/codegen/swap-large-types.rs
index 49a41bb..08c486a 100644
--- a/tests/codegen/swap-large-types.rs
+++ b/tests/codegen/swap-large-types.rs
@@ -12,6 +12,16 @@
// to stack for large types, which is completely unnecessary as the lack of
// overlap means we can just do whatever fits in registers at a time.
+// The tests here (after the first one showing that the problem still exists)
+// are less about testing *exactly* what the codegen is, and more about testing
+// 1) That things are swapped directly from one argument to the other,
+// never going through stack along the way, and
+// 2) That we're doing the swapping for big things using large vector types,
+// rather then `i64` or `<8 x i8>` (or, even worse, `i8`) at a time.
+//
+// (There are separate tests for intrinsics::typed_swap_nonoverlapping that
+// check that it, as an intrinsic, are emitting exactly what it should.)
+
// CHECK-LABEL: @swap_basic
#[no_mangle]
pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) {
@@ -26,55 +36,55 @@ pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) {
}
}
-// This test verifies that the library does something smarter, and thus
-// doesn't need any scratch space on the stack.
-
// CHECK-LABEL: @swap_std
#[no_mangle]
pub fn swap_std(x: &mut KeccakBuffer, y: &mut KeccakBuffer) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i64>
- // CHECK: store <{{[0-9]+}} x i64>
+ // CHECK: load <{{2|4}} x i64>
+ // CHECK: store <{{2|4}} x i64>
swap(x, y)
}
-// Verify that types with usize alignment are swapped via vectored usizes,
-// not falling back to byte-level code.
-
// CHECK-LABEL: @swap_slice
#[no_mangle]
pub fn swap_slice(x: &mut [KeccakBuffer], y: &mut [KeccakBuffer]) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i64>
- // CHECK: store <{{[0-9]+}} x i64>
+ // CHECK: load <{{2|4}} x i64>
+ // CHECK: store <{{2|4}} x i64>
if x.len() == y.len() {
x.swap_with_slice(y);
}
}
-// But for a large align-1 type, vectorized byte copying is what we want.
-
type OneKilobyteBuffer = [u8; 1024];
// CHECK-LABEL: @swap_1kb_slices
#[no_mangle]
pub fn swap_1kb_slices(x: &mut [OneKilobyteBuffer], y: &mut [OneKilobyteBuffer]) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i8>
- // CHECK: store <{{[0-9]+}} x i8>
+
+ // CHECK-NOT: load i32
+ // CHECK-NOT: store i32
+ // CHECK-NOT: load i16
+ // CHECK-NOT: store i16
+ // CHECK-NOT: load i8
+ // CHECK-NOT: store i8
+
+ // CHECK: load <{{2|4}} x i64>{{.+}}align 1,
+ // CHECK: store <{{2|4}} x i64>{{.+}}align 1,
+
+ // CHECK-NOT: load i32
+ // CHECK-NOT: store i32
+ // CHECK-NOT: load i16
+ // CHECK-NOT: store i16
+ // CHECK-NOT: load i8
+ // CHECK-NOT: store i8
+
if x.len() == y.len() {
x.swap_with_slice(y);
}
}
-// This verifies that the 2×read + 2×write optimizes to just 3 memcpys
-// for an unusual type like this. It's not clear whether we should do anything
-// smarter in Rust for these, so for now it's fine to leave these up to the backend.
-// That's not as bad as it might seem, as for example, LLVM will lower the
-// memcpys below to VMOVAPS on YMMs if one enables the AVX target feature.
-// Eventually we'll be able to pass `align_of::<T>` to a const generic and
-// thus pick a smarter chunk size ourselves without huge code duplication.
-
#[repr(align(64))]
pub struct BigButHighlyAligned([u8; 64 * 3]);
@@ -82,9 +92,25 @@ pub fn swap_1kb_slices(x: &mut [OneKilobyteBuffer], y: &mut [OneKilobyteBuffer])
#[no_mangle]
pub fn swap_big_aligned(x: &mut BigButHighlyAligned, y: &mut BigButHighlyAligned) {
// CHECK-NOT: call void @llvm.memcpy
- // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
- // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
- // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
+ // CHECK-NOT: load i32
+ // CHECK-NOT: store i32
+ // CHECK-NOT: load i16
+ // CHECK-NOT: store i16
+ // CHECK-NOT: load i8
+ // CHECK-NOT: store i8
+
+ // CHECK-COUNT-2: load <{{2|4}} x i64>{{.+}}align 64,
+ // CHECK-COUNT-2: store <{{2|4}} x i64>{{.+}}align 64,
+
+ // CHECK-COUNT-2: load <{{2|4}} x i64>{{.+}}align 32,
+ // CHECK-COUNT-2: store <{{2|4}} x i64>{{.+}}align 32,
+
+ // CHECK-NOT: load i32
+ // CHECK-NOT: store i32
+ // CHECK-NOT: load i16
+ // CHECK-NOT: store i16
+ // CHECK-NOT: load i8
+ // CHECK-NOT: store i8
// CHECK-NOT: call void @llvm.memcpy
swap(x, y)
}
diff --git a/tests/codegen/swap-small-types.rs b/tests/codegen/swap-small-types.rs
index 76bb853..7aa613a 100644
--- a/tests/codegen/swap-small-types.rs
+++ b/tests/codegen/swap-small-types.rs
@@ -1,5 +1,7 @@
//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
//@ only-x86_64
+//@ min-llvm-version: 20
+//@ ignore-std-debug-assertions (`ptr::swap_nonoverlapping` has one which blocks some optimizations)
#![crate_type = "lib"]
@@ -27,13 +29,19 @@ pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) {
// CHECK-NOT: alloca
- // Whether `i8` is the best for this is unclear, but
- // might as well record what's actually happening right now.
+ // Swapping `i48` might be cleaner in LLVM-IR here, but `i32`+`i16` isn't bad,
+ // and is closer to the assembly it generates anyway.
- // CHECK: load i8
- // CHECK: load i8
- // CHECK: store i8
- // CHECK: store i8
+ // CHECK-NOT: load{{ }}
+ // CHECK: load i32{{.+}}align 2
+ // CHECK-NEXT: load i32{{.+}}align 2
+ // CHECK-NEXT: store i32{{.+}}align 2
+ // CHECK-NEXT: store i32{{.+}}align 2
+ // CHECK: load i16{{.+}}align 2
+ // CHECK-NEXT: load i16{{.+}}align 2
+ // CHECK-NEXT: store i16{{.+}}align 2
+ // CHECK-NEXT: store i16{{.+}}align 2
+ // CHECK-NOT: store{{ }}
swap(x, y)
}
@@ -76,30 +84,49 @@ pub fn swap_slices<'a>(x: &mut &'a [u32], y: &mut &'a [u32]) {
swap(x, y)
}
-// LLVM doesn't vectorize a loop over 3-byte elements,
-// so we chunk it down to bytes and loop over those instead.
type RGB24 = [u8; 3];
// CHECK-LABEL: @swap_rgb24_slices
#[no_mangle]
pub fn swap_rgb24_slices(x: &mut [RGB24], y: &mut [RGB24]) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i8>
- // CHECK: store <{{[0-9]+}} x i8>
+
+ // CHECK: mul nuw nsw i64 %{{x|y}}.1, 3
+
+ // CHECK: load <{{[0-9]+}} x i64>
+ // CHECK: store <{{[0-9]+}} x i64>
+
+ // CHECK-COUNT-2: load i32
+ // CHECK-COUNT-2: store i32
+ // CHECK-COUNT-2: load i16
+ // CHECK-COUNT-2: store i16
+ // CHECK-COUNT-2: load i8
+ // CHECK-COUNT-2: store i8
if x.len() == y.len() {
x.swap_with_slice(y);
}
}
-// This one has a power-of-two size, so we iterate over it directly
type RGBA32 = [u8; 4];
// CHECK-LABEL: @swap_rgba32_slices
#[no_mangle]
pub fn swap_rgba32_slices(x: &mut [RGBA32], y: &mut [RGBA32]) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i32>
- // CHECK: store <{{[0-9]+}} x i32>
+
+ // Because the size in bytes in a multiple of 4, we can skip the smallest sizes.
+
+ // CHECK: load <{{[0-9]+}} x i64>
+ // CHECK: store <{{[0-9]+}} x i64>
+
+ // CHECK-COUNT-2: load i32
+ // CHECK-COUNT-2: store i32
+
+ // CHECK-NOT: load i16
+ // CHECK-NOT: store i16
+ // CHECK-NOT: load i8
+ // CHECK-NOT: store i8
+
if x.len() == y.len() {
x.swap_with_slice(y);
}
@@ -113,8 +140,8 @@ pub fn swap_rgba32_slices(x: &mut [RGBA32], y: &mut [RGBA32]) {
#[no_mangle]
pub fn swap_string_slices(x: &mut [String], y: &mut [String]) {
// CHECK-NOT: alloca
- // CHECK: load <{{[0-9]+}} x i64>
- // CHECK: store <{{[0-9]+}} x i64>
+ // CHECK: load <{{[0-9]+}} x i64>{{.+}}, align 8,
+ // CHECK: store <{{[0-9]+}} x i64>{{.+}}, align 8,
if x.len() == y.len() {
x.swap_with_slice(y);
}
@@ -130,6 +157,26 @@ pub struct Packed {
#[no_mangle]
pub fn swap_packed_structs(x: &mut Packed, y: &mut Packed) {
// CHECK-NOT: alloca
+
+ // CHECK-NOT: load
+ // CHECK-NOT: store
+
+ // CHECK: %[[A:.+]] = load i64, ptr %x, align 1,
+ // CHECK-NEXT: %[[B:.+]] = load i64, ptr %y, align 1,
+ // CHECK-NEXT: store i64 %[[B]], ptr %x, align 1,
+ // CHECK-NEXT: store i64 %[[A]], ptr %y, align 1,
+
+ // CHECK-NOT: load
+ // CHECK-NOT: store
+
+ // CHECK: %[[C:.+]] = load i8, ptr %[[X8:.+]], align 1,
+ // CHECK-NEXT: %[[D:.+]] = load i8, ptr %[[Y8:.+]], align 1,
+ // CHECK-NEXT: store i8 %[[D]], ptr %[[X8]], align 1,
+ // CHECK-NEXT: store i8 %[[C]], ptr %[[Y8]], align 1,
+
+ // CHECK-NOT: load
+ // CHECK-NOT: store
+
// CHECK: ret void
swap(x, y)
}
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 9f68d74..398c9a5 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled --edition=2021
+//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
+//@ edition: 2021
//@ only-x86_64
//@ revisions: NINETEEN TWENTY
//@[NINETEEN] exact-llvm-major-version: 19
diff --git a/tests/crashes/119095.rs b/tests/crashes/119095.rs
index 28742e0..9b6c976 100644
--- a/tests/crashes/119095.rs
+++ b/tests/crashes/119095.rs
@@ -1,5 +1,5 @@
//@ known-bug: #119095
-//@ compile-flags: --edition=2021
+//@ edition: 2021
fn any<T>() -> T {
loop {}
diff --git a/tests/crashes/120016.rs b/tests/crashes/120016.rs
index faba1af..7eda330 100644
--- a/tests/crashes/120016.rs
+++ b/tests/crashes/120016.rs
@@ -1,5 +1,6 @@
//@ known-bug: #120016
-//@ compile-flags: -Zcrate-attr=feature(const_async_blocks) --edition=2021
+//@ compile-flags: -Zcrate-attr=feature(const_async_blocks)
+//@ edition: 2021
#![feature(type_alias_impl_trait, const_async_blocks)]
diff --git a/tests/crashes/127033.rs b/tests/crashes/127033.rs
index 919c9df..52b880e 100644
--- a/tests/crashes/127033.rs
+++ b/tests/crashes/127033.rs
@@ -1,5 +1,5 @@
//@ known-bug: #127033
-//@ compile-flags: --edition=2021
+//@ edition: 2021
pub trait RaftLogStorage {
fn save_vote(vote: ()) -> impl std::future::Future + Send;
diff --git a/tests/crashes/128094.rs b/tests/crashes/128094.rs
index 5f0ae10..56d09d7 100644
--- a/tests/crashes/128094.rs
+++ b/tests/crashes/128094.rs
@@ -1,5 +1,6 @@
//@ known-bug: rust-lang/rust#128094
-//@ compile-flags: -Zmir-enable-passes=+GVN --edition=2018
+//@ compile-flags: -Zmir-enable-passes=+GVN
+//@ edition: 2018
pub enum Request {
TestSome(T),
diff --git a/tests/crashes/129372.rs b/tests/crashes/129372.rs
deleted file mode 100644
index 43be01b..0000000
--- a/tests/crashes/129372.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-//@ known-bug: #129372
-//@ compile-flags: -Cdebuginfo=2 -Copt-level=0
-
-pub struct Wrapper<T>(T);
-struct Struct;
-
-pub trait TraitA {
- type AssocA<'t>;
-}
-pub trait TraitB {
- type AssocB;
-}
-
-pub fn helper(v: impl MethodTrait) {
- let _local_that_causes_ice = v.method();
-}
-
-pub fn main() {
- helper(Wrapper(Struct));
-}
-
-pub trait MethodTrait {
- type Assoc<'a>;
-
- fn method(self) -> impl for<'a> FnMut(&'a ()) -> Self::Assoc<'a>;
-}
-
-impl<T: TraitB> MethodTrait for T
-where
- <T as TraitB>::AssocB: TraitA,
-{
- type Assoc<'a> = <T::AssocB as TraitA>::AssocA<'a>;
-
- fn method(self) -> impl for<'a> FnMut(&'a ()) -> Self::Assoc<'a> {
- move |_| loop {}
- }
-}
-
-impl<T, B> TraitB for Wrapper<B>
-where
- B: TraitB<AssocB = T>,
-{
- type AssocB = T;
-}
-
-impl TraitB for Struct {
- type AssocB = Struct;
-}
-
-impl TraitA for Struct {
- type AssocA<'t> = Self;
-}
diff --git a/tests/crashes/132103.rs b/tests/crashes/132103.rs
index 5bf4792..e2d8378 100644
--- a/tests/crashes/132103.rs
+++ b/tests/crashes/132103.rs
@@ -1,5 +1,6 @@
//@ known-bug: #132103
-//@compile-flags: -Zvalidate-mir --edition=2018 -Zinline-mir=yes
+//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
+//@ edition: 2018
use core::future::{async_drop_in_place, Future};
use core::mem::{self};
use core::pin::pin;
diff --git a/tests/crashes/132430.rs b/tests/crashes/132430.rs
index 995bdf0..81c8c6d 100644
--- a/tests/crashes/132430.rs
+++ b/tests/crashes/132430.rs
@@ -1,6 +1,7 @@
//@ known-bug: #132430
-//@compile-flags: --edition=2018 --crate-type=lib
+//@ compile-flags: --crate-type=lib
+//@ edition: 2018
#![feature(cmse_nonsecure_entry)]
struct Test;
diff --git a/tests/crashes/135128.rs b/tests/crashes/135128.rs
index a8fd1ae..c718b75 100644
--- a/tests/crashes/135128.rs
+++ b/tests/crashes/135128.rs
@@ -1,5 +1,6 @@
//@ known-bug: #135128
-//@ compile-flags: -Copt-level=1 --edition=2021
+//@ compile-flags: -Copt-level=1
+//@ edition: 2021
#![feature(trivial_bounds)]
diff --git a/tests/crashes/135470.rs b/tests/crashes/135470.rs
index 7d357a9..efa017b 100644
--- a/tests/crashes/135470.rs
+++ b/tests/crashes/135470.rs
@@ -1,5 +1,6 @@
//@ known-bug: #135470
-//@ compile-flags: --edition=2021 -Copt-level=0
+//@ compile-flags: -Copt-level=0
+//@ edition: 2021
use std::future::Future;
trait Access {
diff --git a/tests/crashes/135646.rs b/tests/crashes/135646.rs
index 67b0ad9..841ea5b8 100644
--- a/tests/crashes/135646.rs
+++ b/tests/crashes/135646.rs
@@ -1,5 +1,7 @@
//@ known-bug: #135646
-//@ compile-flags: --edition=2024 -Zpolonius=next
+//@ compile-flags: -Zpolonius=next
+//@ edition: 2024
+
fn main() {
&{ [1, 2, 3][4] };
}
diff --git a/tests/crashes/135668.rs b/tests/crashes/135668.rs
index 8126a65..00d7b5d 100644
--- a/tests/crashes/135668.rs
+++ b/tests/crashes/135668.rs
@@ -1,5 +1,5 @@
//@ known-bug: #135668
-//@ compile-flags: --edition=2021
+//@ edition: 2021
use std::future::Future;
pub async fn foo() {
diff --git a/tests/crashes/137467-1.rs b/tests/crashes/137467-1.rs
index 1d62cba..b6bff2b 100644
--- a/tests/crashes/137467-1.rs
+++ b/tests/crashes/137467-1.rs
@@ -1,5 +1,5 @@
//@ known-bug: #137467
-//@ compile-flags: --edition=2021
+//@ edition: 2021
enum Camera {
Normal { base_transform: i32 },
Volume { transform: i32 },
diff --git a/tests/crashes/137467-2.rs b/tests/crashes/137467-2.rs
index 151d6a0..a70ea92 100644
--- a/tests/crashes/137467-2.rs
+++ b/tests/crashes/137467-2.rs
@@ -1,5 +1,5 @@
//@ known-bug: #137467
-//@ compile-flags: --edition=2021
+//@ edition: 2021
enum Camera {
Normal { base_transform: i32 },
diff --git a/tests/crashes/137467-3.rs b/tests/crashes/137467-3.rs
index 2140fe0..cb81a9a 100644
--- a/tests/crashes/137467-3.rs
+++ b/tests/crashes/137467-3.rs
@@ -1,5 +1,5 @@
//@ known-bug: #137467
-//@ compile-flags: --edition=2021
+//@ edition: 2021
fn meow(x: (u32, u32, u32)) {
let f = || {
diff --git a/tests/crashes/137916.rs b/tests/crashes/137916.rs
index 3d6b0e0..b25e7b2 100644
--- a/tests/crashes/137916.rs
+++ b/tests/crashes/137916.rs
@@ -1,5 +1,5 @@
//@ known-bug: #137916
-//@ compile-flags: --edition=2021
+//@ edition: 2021
use std::ptr::null;
async fn a() -> Box<dyn Send> {
diff --git a/tests/debuginfo/coroutine-closure.rs b/tests/debuginfo/coroutine-closure.rs
index ffb6ae6..0025310 100644
--- a/tests/debuginfo/coroutine-closure.rs
+++ b/tests/debuginfo/coroutine-closure.rs
@@ -1,6 +1,7 @@
#![feature(async_closure)]
//@ only-cdb
-//@ compile-flags:-g --edition=2021
+//@ compile-flags: -g
+//@ edition: 2021
// === CDB TESTS ==================================================================================
diff --git a/tests/incremental/issue-85360-eval-obligation-ice.rs b/tests/incremental/issue-85360-eval-obligation-ice.rs
index 6efae1a..70bb43f 100644
--- a/tests/incremental/issue-85360-eval-obligation-ice.rs
+++ b/tests/incremental/issue-85360-eval-obligation-ice.rs
@@ -1,6 +1,7 @@
//@ revisions:cfail1 cfail2
-//@[cfail1] compile-flags: --crate-type=lib --edition=2021 -Zassert-incr-state=not-loaded
-//@[cfail2] compile-flags: --crate-type=lib --edition=2021 -Zassert-incr-state=loaded
+//@[cfail1] compile-flags: --crate-type=lib -Zassert-incr-state=not-loaded
+//@[cfail2] compile-flags: --crate-type=lib -Zassert-incr-state=loaded
+//@ edition: 2021
//@ build-pass
use core::any::Any;
diff --git a/tests/mir-opt/ergonomic-clones/closure.rs b/tests/mir-opt/ergonomic-clones/closure.rs
new file mode 100644
index 0000000..682f484
--- /dev/null
+++ b/tests/mir-opt/ergonomic-clones/closure.rs
@@ -0,0 +1,55 @@
+#![crate_type = "lib"]
+#![feature(ergonomic_clones)]
+#![allow(incomplete_features)]
+
+use std::clone::UseCloned;
+
+pub fn ergonomic_clone_closure_move() -> String {
+ // CHECK-LABEL: fn ergonomic_clone_closure_move(
+ // CHECK: _0 = move (_1.0: std::string::String);
+ // CHECK-NOT: <String as Clone>::clone
+ let s = String::from("hi");
+
+ let cl = use || s;
+ cl()
+}
+
+#[derive(Clone)]
+struct Foo;
+
+impl UseCloned for Foo {}
+
+pub fn ergonomic_clone_closure_use_cloned() -> Foo {
+ // CHECK-LABEL: fn ergonomic_clone_closure_use_cloned(
+ // CHECK: <Foo as Clone>::clone
+ let f = Foo;
+
+ let f1 = use || f;
+
+ let f2 = use || f;
+
+ f
+}
+
+pub fn ergonomic_clone_closure_copy() -> i32 {
+ // CHECK-LABEL: fn ergonomic_clone_closure_copy(
+ // CHECK: _0 = copy ((*_1).0: i32);
+ // CHECK-NOT: <i32 as Clone>::clone
+ let i = 1;
+
+ let i1 = use || i;
+
+ let i2 = use || i;
+
+ i
+}
+
+pub fn ergonomic_clone_closure_use_cloned_generics<T: UseCloned>(f: T) -> T {
+ // CHECK-LABEL: fn ergonomic_clone_closure_use_cloned_generics(
+ // CHECK: <T as Clone>::clone
+ let f1 = use || f;
+
+ let f2 = use || f;
+
+ f
+}
diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp
new file mode 100644
index 0000000..872a6a4
--- /dev/null
+++ b/tests/pretty/hir-delegation.pp
@@ -0,0 +1,23 @@
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-delegation.pp
+
+#![allow(incomplete_features)]#![feature(fn_delegation)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn b<C>(e: C) { }
+
+trait G {
+ fn b(arg0: _) -> _ { b({ }) }
+}
+
+mod m {
+ fn add(a: u32, b: u32) -> u32 { a + b }
+}
+
+fn add(arg0: _, arg1: _) -> _ { m::add(arg0, arg1) }
+
+fn main() { { let _ = add(1, 2); }; }
diff --git a/tests/pretty/hir-delegation.rs b/tests/pretty/hir-delegation.rs
new file mode 100644
index 0000000..9e351a1
--- /dev/null
+++ b/tests/pretty/hir-delegation.rs
@@ -0,0 +1,22 @@
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-delegation.pp
+
+#![allow(incomplete_features)]
+#![feature(fn_delegation)]
+
+fn b<C>(e: C) {}
+
+trait G {
+ reuse b {}
+}
+
+mod m {
+ pub fn add(a: u32, b: u32) -> u32 { a + b }
+}
+
+reuse m::add;
+
+fn main() {
+ _ = add(1, 2);
+}
diff --git a/tests/run-make/dirty-incr-due-to-hard-link/rmake.rs b/tests/run-make/dirty-incr-due-to-hard-link/rmake.rs
new file mode 100644
index 0000000..942b667
--- /dev/null
+++ b/tests/run-make/dirty-incr-due-to-hard-link/rmake.rs
@@ -0,0 +1,32 @@
+//@ only-x86_64-unknown-linux-gnu
+
+// Regression test for the incremental bug in <https://github.com/rust-lang/rust/issues/139407>.
+//
+// A detailed explanation is described in <https://github.com/rust-lang/rust/pull/139453>,
+// however the gist of the issue is that hard-linking temporary files can interact strangely
+// across incremental sessions that are not finalized due to errors originating from the
+// codegen backend.
+
+use run_make_support::{run, rustc};
+
+fn main() {
+ let mk_rustc = || {
+ let mut rustc = rustc();
+ rustc.input("test.rs").incremental("incr").arg("-Csave-temps").output("test");
+ rustc
+ };
+
+ // Revision 1
+ mk_rustc().cfg("rpass1").run();
+
+ run("test");
+
+ // Revision 2
+ mk_rustc().cfg("cfail2").run_fail();
+ // Expected to fail.
+
+ // Revision 3
+ mk_rustc().cfg("rpass3").run();
+
+ run("test");
+}
diff --git a/tests/run-make/dirty-incr-due-to-hard-link/test.rs b/tests/run-make/dirty-incr-due-to-hard-link/test.rs
new file mode 100644
index 0000000..dba5a6b
--- /dev/null
+++ b/tests/run-make/dirty-incr-due-to-hard-link/test.rs
@@ -0,0 +1,31 @@
+#[inline(never)]
+#[cfg(any(rpass1, rpass3))]
+fn a() -> i32 {
+ 0
+}
+
+#[cfg(any(cfail2))]
+fn a() -> i32 {
+ 1
+}
+
+fn main() {
+ evil::evil();
+ assert_eq!(a(), 0);
+}
+
+mod evil {
+ #[cfg(any(rpass1, rpass3))]
+ pub fn evil() {
+ unsafe {
+ std::arch::asm!("/* */");
+ }
+ }
+
+ #[cfg(any(cfail2))]
+ pub fn evil() {
+ unsafe {
+ std::arch::asm!("missing");
+ }
+ }
+}
diff --git a/tests/run-make/unstable-feature-usage-metrics-incremental/main.rs b/tests/run-make/unstable-feature-usage-metrics-incremental/main.rs
new file mode 100644
index 0000000..f970d39
--- /dev/null
+++ b/tests/run-make/unstable-feature-usage-metrics-incremental/main.rs
@@ -0,0 +1,16 @@
+#![feature(ascii_char)] // random lib feature
+#![feature(box_patterns)] // random lang feature
+
+// picked arbitrary unstable features, just need a random lib and lang feature, ideally ones that
+// won't be stabilized any time soon so we don't have to update this test
+fn main() {
+ for s in quix("foo/bar") {
+ print!("{s}");
+ }
+ println!();
+}
+
+// need a latebound var to trigger the incremental compilation ICE
+fn quix(foo: &str) -> impl Iterator<Item = &'_ str> + '_ {
+ foo.split('/')
+}
diff --git a/tests/run-make/unstable-feature-usage-metrics-incremental/rmake.rs b/tests/run-make/unstable-feature-usage-metrics-incremental/rmake.rs
new file mode 100644
index 0000000..7e070d8
--- /dev/null
+++ b/tests/run-make/unstable-feature-usage-metrics-incremental/rmake.rs
@@ -0,0 +1,94 @@
+//! This test checks if unstable feature usage metric dump files `unstable-feature-usage*.json` work
+//! as expected.
+//!
+//! - Basic sanity checks on a default ICE dump.
+//!
+//! See <https://github.com/rust-lang/rust/issues/129485>.
+//!
+//! # Test history
+//!
+//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming
+//! those will be present in this test as well on the same platform
+
+//@ ignore-windows
+//FIXME(#128911): still flakey on i686-mingw.
+
+use std::path::{Path, PathBuf};
+
+use run_make_support::rfs::create_dir_all;
+use run_make_support::{
+ cwd, filename_contains, has_extension, rfs, run_in_tmpdir, rustc, serde_json,
+ shallow_find_files,
+};
+
+fn find_feature_usage_metrics<P: AsRef<Path>>(dir: P) -> Vec<PathBuf> {
+ shallow_find_files(dir, |path| {
+ if filename_contains(path, "unstable_feature_usage") && has_extension(path, "json") {
+ true
+ } else {
+ dbg!(path);
+ false
+ }
+ })
+}
+
+fn main() {
+ test_metrics_dump();
+ test_metrics_errors();
+}
+
+#[track_caller]
+fn test_metrics_dump() {
+ run_in_tmpdir(|| {
+ let metrics_dir = cwd().join("metrics");
+ create_dir_all(&metrics_dir);
+ rustc()
+ .input("main.rs")
+ .incremental("incremental")
+ .env("RUST_BACKTRACE", "short")
+ .arg(format!("-Zmetrics-dir={}", metrics_dir.display()))
+ .run();
+ let mut metrics = find_feature_usage_metrics(&metrics_dir);
+ let json_path =
+ metrics.pop().expect("there should be one metrics file in the output directory");
+
+ // After the `pop` above, there should be no files left.
+ assert!(
+ metrics.is_empty(),
+ "there should be no more than one metrics file in the output directory"
+ );
+
+ let message = rfs::read_to_string(json_path);
+ let mut parsed: serde_json::Value =
+ serde_json::from_str(&message).expect("metrics should be dumped as json");
+ // remove timestamps
+ assert!(parsed["lib_features"][0]["timestamp"].is_number());
+ assert!(parsed["lang_features"][0]["timestamp"].is_number());
+ parsed["lib_features"][0]["timestamp"] = serde_json::json!(null);
+ parsed["lang_features"][0]["timestamp"] = serde_json::json!(null);
+ let expected = serde_json::json!(
+ {
+ "lib_features":[{"symbol":"ascii_char", "timestamp":null}],
+ "lang_features":[{"symbol":"box_patterns","since":null, "timestamp":null}]
+ }
+ );
+
+ assert_eq!(expected, parsed);
+ });
+}
+
+#[track_caller]
+fn test_metrics_errors() {
+ run_in_tmpdir(|| {
+ rustc()
+ .input("main.rs")
+ .incremental("incremental")
+ .env("RUST_BACKTRACE", "short")
+ .arg("-Zmetrics-dir=invaliddirectorythatdefinitelydoesntexist")
+ .run_fail()
+ .assert_stderr_contains(
+ "error: cannot dump feature usage metrics: No such file or directory",
+ )
+ .assert_stdout_not_contains("internal compiler error");
+ });
+}
diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml
index 4ab5b83..11d3696 100644
--- a/tests/rustdoc-gui/settings.goml
+++ b/tests/rustdoc-gui/settings.goml
@@ -314,6 +314,13 @@
// Check that setting-line has the same margin in this mode as in the popover.
assert-css: (".setting-line", {"margin": |setting_line_margin|})
+// We will check that the checkboxes size doesn't change either.
+assert-size: (
+ "#settings label > input[type='checkbox']",
+ {"width": 19, "height": 19},
+ ALL,
+)
+
// We now check the display with JS disabled.
assert-false: "noscript section"
javascript: false
@@ -327,3 +334,10 @@
set-window-size: (300, 1000)
wait-for: "#settings"
assert-css: (".setting-radio", {"cursor": "pointer"})
+
+// We ensure that the checkboxes size didn't change.
+assert-size: (
+ "#settings label > input[type='checkbox']",
+ {"width": 19, "height": 19},
+ ALL,
+)
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs
index d8c4310..1ed6769 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs
+++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs
@@ -1,7 +1,8 @@
// FIXME: if/when the output of the test harness can be tested on its own, this test should be
// adapted to use that, and that normalize line can go away
-//@ compile-flags:--test --edition 2021
+//@ compile-flags: --test
+//@ edition: 2021
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@ failure-status: 101
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout
index 63d987d..9f4d60e 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout
+++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout
@@ -1,14 +1,14 @@
running 1 test
-test $DIR/failed-doctest-should-panic-2021.rs - Foo (line 9) ... FAILED
+test $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10) ... FAILED
failures:
----- $DIR/failed-doctest-should-panic-2021.rs - Foo (line 9) stdout ----
+---- $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10) stdout ----
Test executable succeeded, but it's marked `should_panic`.
failures:
- $DIR/failed-doctest-should-panic-2021.rs - Foo (line 9)
+ $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10)
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
diff --git a/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs b/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs
index 636c3c8..bcfb790 100644
--- a/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs
+++ b/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs
@@ -3,7 +3,8 @@
//@ check-pass
//@ aux-build: inner-crate-doc.rs
-//@ compile-flags: --extern inner_crate_doc --edition 2018
+//@ compile-flags: --extern inner_crate_doc
+//@ edition: 2018
/// Import doc comment [inner_crate_doc]
#[doc(inline)]
diff --git a/tests/rustdoc-ui/multi-par-footnote.rs b/tests/rustdoc-ui/multi-par-footnote.rs
new file mode 100644
index 0000000..bb6a85d
--- /dev/null
+++ b/tests/rustdoc-ui/multi-par-footnote.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+//@ compile-flags:--test
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+// Regression test for #139064.
+
+/// Example
+///
+/// Footnote with multiple paragraphs[^multiple]
+///
+/// [^multiple]:
+/// One
+///
+/// Two
+///
+/// Three
+pub fn add(left: u64, right: u64) -> u64 {
+ left + right
+}
diff --git a/tests/rustdoc-ui/multi-par-footnote.stdout b/tests/rustdoc-ui/multi-par-footnote.stdout
new file mode 100644
index 0000000..7326c0a
--- /dev/null
+++ b/tests/rustdoc-ui/multi-par-footnote.stdout
@@ -0,0 +1,5 @@
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc/auxiliary/primitive-doc.rs b/tests/rustdoc/auxiliary/primitive-doc.rs
index a7253ed..859716c 100644
--- a/tests/rustdoc/auxiliary/primitive-doc.rs
+++ b/tests/rustdoc/auxiliary/primitive-doc.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --crate-type lib --edition 2018
+//@ compile-flags: --crate-type lib
+//@ edition: 2018
#![feature(rustc_attrs)]
#![feature(no_core)]
diff --git a/tests/rustdoc/auxiliary/primitive-reexport.rs b/tests/rustdoc/auxiliary/primitive-reexport.rs
index 18b5703..7c85038 100644
--- a/tests/rustdoc/auxiliary/primitive-reexport.rs
+++ b/tests/rustdoc/auxiliary/primitive-reexport.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --emit metadata --crate-type lib --edition 2018
+//@ compile-flags: --emit metadata --crate-type lib
+//@ edition: 2018
#![crate_name = "foo"]
diff --git a/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs b/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs
index 7cec30c..30834bd 100644
--- a/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs
+++ b/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs
@@ -6,7 +6,8 @@
//@ aux-build:empty2.rs
//@ aux-crate:priv:empty2=empty2.rs
//@ build-aux-docs
-//@ compile-flags:-Z unstable-options --edition 2018
+//@ compile-flags:-Z unstable-options
+//@ edition: 2018
//@ has extern_crate_only_used_in_link/index.html
//@ has - '//a[@href="../issue_66159_1/struct.Something.html"]' 'issue_66159_1::Something'
diff --git a/tests/rustdoc/primitive-reexport.rs b/tests/rustdoc/primitive-reexport.rs
index eb25574..9b23b24 100644
--- a/tests/rustdoc/primitive-reexport.rs
+++ b/tests/rustdoc/primitive-reexport.rs
@@ -1,5 +1,6 @@
//@ aux-build: primitive-reexport.rs
-//@ compile-flags:--extern foo --edition 2018
+//@ compile-flags: --extern foo
+//@ edition: 2018
#![crate_name = "bar"]
diff --git a/tests/rustdoc/primitive-slice-auto-trait.rs b/tests/rustdoc/primitive-slice-auto-trait.rs
index e78d1d9..647c1cc 100644
--- a/tests/rustdoc/primitive-slice-auto-trait.rs
+++ b/tests/rustdoc/primitive-slice-auto-trait.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --crate-type lib --edition 2018
+//@ compile-flags: --crate-type lib
+//@ edition: 2018
#![crate_name = "foo"]
#![feature(rustc_attrs)]
diff --git a/tests/rustdoc/primitive-tuple-auto-trait.rs b/tests/rustdoc/primitive-tuple-auto-trait.rs
index 045478e..51300bd 100644
--- a/tests/rustdoc/primitive-tuple-auto-trait.rs
+++ b/tests/rustdoc/primitive-tuple-auto-trait.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --crate-type lib --edition 2018
+//@ compile-flags: --crate-type lib
+//@ edition: 2018
#![crate_name = "foo"]
#![feature(rustc_attrs)]
diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive-tuple-variadic.rs
index d142729..bab5eaa 100644
--- a/tests/rustdoc/primitive-tuple-variadic.rs
+++ b/tests/rustdoc/primitive-tuple-variadic.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --crate-type lib --edition 2018
+//@ compile-flags: --crate-type lib
+//@ edition: 2018
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
diff --git a/tests/rustdoc/primitive-unit-auto-trait.rs b/tests/rustdoc/primitive-unit-auto-trait.rs
index 6cae094..7dada1f 100644
--- a/tests/rustdoc/primitive-unit-auto-trait.rs
+++ b/tests/rustdoc/primitive-unit-auto-trait.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --crate-type lib --edition 2018
+//@ compile-flags: --crate-type lib
+//@ edition: 2018
#![crate_name = "foo"]
#![feature(rustc_attrs)]
diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs
index ffc19b1..fa651ba 100644
--- a/tests/ui-fulldeps/run-compiler-twice.rs
+++ b/tests/ui-fulldeps/run-compiler-twice.rs
@@ -70,6 +70,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path
hash_untracked_state: None,
register_lints: None,
override_queries: None,
+ extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES,
diff --git a/tests/ui/associated-types/impl-wf-cycle-4.rs b/tests/ui/associated-types/impl-wf-cycle-4.rs
index bfa8adc..1c1b399 100644
--- a/tests/ui/associated-types/impl-wf-cycle-4.rs
+++ b/tests/ui/associated-types/impl-wf-cycle-4.rs
@@ -2,7 +2,7 @@
type ToMatch;
}
-impl<T> Filter for T //~ ERROR overflow evaluating the requirement
+impl<T> Filter for T //~ ERROR cycle detected when
where
T: Fn(Self::ToMatch),
{
diff --git a/tests/ui/associated-types/impl-wf-cycle-4.stderr b/tests/ui/associated-types/impl-wf-cycle-4.stderr
index cdbac26..c966579 100644
--- a/tests/ui/associated-types/impl-wf-cycle-4.stderr
+++ b/tests/ui/associated-types/impl-wf-cycle-4.stderr
@@ -1,4 +1,4 @@
-error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
+error[E0391]: cycle detected when computing normalized predicates of `<impl at $DIR/impl-wf-cycle-4.rs:5:1: 7:26>`
--> $DIR/impl-wf-cycle-4.rs:5:1
|
LL | / impl<T> Filter for T
@@ -6,20 +6,23 @@
LL | | T: Fn(Self::ToMatch),
| |_________________________^
|
-note: required for `T` to implement `Filter`
- --> $DIR/impl-wf-cycle-4.rs:5:9
+note: ...which requires computing whether `<impl at $DIR/impl-wf-cycle-4.rs:5:1: 7:26>` has a guaranteed unsized self type...
+ --> $DIR/impl-wf-cycle-4.rs:5:1
|
-LL | impl<T> Filter for T
- | ^^^^^^ ^
-LL | where
-LL | T: Fn(Self::ToMatch),
- | ----------------- unsatisfied trait bound introduced here
-note: associated types for the current `impl` cannot be restricted in `where` clauses
- --> $DIR/impl-wf-cycle-4.rs:7:11
+LL | / impl<T> Filter for T
+LL | | where
+LL | | T: Fn(Self::ToMatch),
+ | |_________________________^
+ = note: ...which again requires computing normalized predicates of `<impl at $DIR/impl-wf-cycle-4.rs:5:1: 7:26>`, completing the cycle
+note: cycle used when checking that `<impl at $DIR/impl-wf-cycle-4.rs:5:1: 7:26>` is well-formed
+ --> $DIR/impl-wf-cycle-4.rs:5:1
|
-LL | T: Fn(Self::ToMatch),
- | ^^^^^^^^^^^^^
+LL | / impl<T> Filter for T
+LL | | where
+LL | | T: Fn(Self::ToMatch),
+ | |_________________________^
+ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 1 previous error
-For more information about this error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
index 069744a..12dca58 100644
--- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
+//@ compile-flags: -Zvalidate-mir --crate-type=lib -Copt-level=3
+//@ edition: 2018
fn main() {}
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
index 52697ba..03fa220 100644
--- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `x` which is behind a mutable reference
- --> $DIR/closure-shim-borrowck-error.rs:10:18
+ --> $DIR/closure-shim-borrowck-error.rs:11:18
|
LL | needs_fn_mut(async || {
| ^^^^^^^^ `x` is moved here
@@ -11,7 +11,7 @@
| move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
|
note: if `Ty` implemented `Clone`, you could clone the value
- --> $DIR/closure-shim-borrowck-error.rs:16:1
+ --> $DIR/closure-shim-borrowck-error.rs:17:1
|
LL | x.hello();
| - you could clone this value
diff --git a/tests/ui/async-await/issue-60709.rs b/tests/ui/async-await/issue-60709.rs
index 8634d6f..a3f54d7 100644
--- a/tests/ui/async-await/issue-60709.rs
+++ b/tests/ui/async-await/issue-60709.rs
@@ -1,6 +1,7 @@
// This used to compile the future down to ud2, due to uninhabited types being
// handled incorrectly in coroutines.
-//@ compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018
+//@ compile-flags: -Copt-level=z -Cdebuginfo=2
+//@ edition: 2018
//@ run-pass
diff --git a/tests/ui/async-await/issues/issue-59972.rs b/tests/ui/async-await/issues/issue-59972.rs
index c30477f..e64a856 100644
--- a/tests/ui/async-await/issues/issue-59972.rs
+++ b/tests/ui/async-await/issues/issue-59972.rs
@@ -4,7 +4,8 @@
//@ run-pass
-//@ compile-flags: --edition=2018 -Aunused
+//@ compile-flags: -Aunused
+//@ edition: 2018
pub enum Uninhabited { }
diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs
index 2f2cd8d..a916bd8 100644
--- a/tests/ui/autodiff/autodiff_illegal.rs
+++ b/tests/ui/autodiff/autodiff_illegal.rs
@@ -63,7 +63,7 @@ fn dummy() {
// Malformed, where args?
#[autodiff]
pub fn f7(x: f64) {
- //~^ ERROR autodiff must be applied to function
+ //~^ ERROR autodiff requires at least a name and mode
unimplemented!()
}
@@ -77,7 +77,7 @@ pub fn f8(x: f64) {
// Invalid attribute syntax
#[autodiff = ""]
pub fn f9(x: f64) {
- //~^ ERROR autodiff must be applied to function
+ //~^ ERROR autodiff requires at least a name and mode
unimplemented!()
}
diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr
index 3752b27..b119f61 100644
--- a/tests/ui/autodiff/autodiff_illegal.stderr
+++ b/tests/ui/autodiff/autodiff_illegal.stderr
@@ -62,7 +62,7 @@
LL | let add_one_v2 = |x: u32| -> u32 { x + 1 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: autodiff must be applied to function
+error: autodiff requires at least a name and mode
--> $DIR/autodiff_illegal.rs:65:1
|
LL | / pub fn f7(x: f64) {
@@ -80,7 +80,7 @@
LL | | }
| |_^
-error: autodiff must be applied to function
+error: autodiff requires at least a name and mode
--> $DIR/autodiff_illegal.rs:79:1
|
LL | / pub fn f9(x: f64) {
diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs
index 35e545a..349c494 100644
--- a/tests/ui/cfg/cfg_false_no_std-2.rs
+++ b/tests/ui/cfg/cfg_false_no_std-2.rs
@@ -1,7 +1,6 @@
// Error, the linked empty library is `no_std` and doesn't provide a panic handler.
-//@ compile-flags: --error-format=human
-//@ error-pattern: `#[panic_handler]` function required, but not found
+//@ dont-require-annotations:ERROR
//@ dont-check-compiler-stderr
//@ aux-build: cfg_false_lib_no_std_before.rs
@@ -11,6 +10,7 @@
fn main() {}
-// FIXME: The second error is target-dependent.
-//FIXME~? ERROR `#[panic_handler]` function required, but not found
+//~? ERROR `#[panic_handler]` function required, but not found
+// FIXME: This error is target-dependent, could be served by some "optional error" annotation
+// instead of `dont-require-annotations`.
//FIXME~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/check-cfg/raw-keywords.edition2015.stderr b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
index 8ca33e0..29c1a71 100644
--- a/tests/ui/check-cfg/raw-keywords.edition2015.stderr
+++ b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
@@ -1,5 +1,5 @@
warning: unexpected `cfg` condition name: `tru`
- --> $DIR/raw-keywords.rs:14:7
+ --> $DIR/raw-keywords.rs:15:7
|
LL | #[cfg(tru)]
| ^^^ help: there is a config with a similar name: `r#true`
@@ -9,7 +9,7 @@
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition name: `r#false`
- --> $DIR/raw-keywords.rs:19:7
+ --> $DIR/raw-keywords.rs:20:7
|
LL | #[cfg(r#false)]
| ^^^^^^^
@@ -19,7 +19,7 @@
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `await`
- --> $DIR/raw-keywords.rs:27:29
+ --> $DIR/raw-keywords.rs:28:29
|
LL | #[cfg_attr(edition2015, cfg(await))]
| ^^^^^
@@ -28,7 +28,7 @@
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `raw`
- --> $DIR/raw-keywords.rs:33:7
+ --> $DIR/raw-keywords.rs:34:7
|
LL | #[cfg(r#raw)]
| ^^^^^
diff --git a/tests/ui/check-cfg/raw-keywords.edition2021.stderr b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
index cce5572..cc37026 100644
--- a/tests/ui/check-cfg/raw-keywords.edition2021.stderr
+++ b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
@@ -1,5 +1,5 @@
warning: unexpected `cfg` condition name: `tru`
- --> $DIR/raw-keywords.rs:14:7
+ --> $DIR/raw-keywords.rs:15:7
|
LL | #[cfg(tru)]
| ^^^ help: there is a config with a similar name: `r#true`
@@ -9,7 +9,7 @@
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition name: `r#false`
- --> $DIR/raw-keywords.rs:19:7
+ --> $DIR/raw-keywords.rs:20:7
|
LL | #[cfg(r#false)]
| ^^^^^^^
@@ -19,7 +19,7 @@
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `r#await`
- --> $DIR/raw-keywords.rs:28:29
+ --> $DIR/raw-keywords.rs:29:29
|
LL | #[cfg_attr(edition2021, cfg(r#await))]
| ^^^^^^^
@@ -28,7 +28,7 @@
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `raw`
- --> $DIR/raw-keywords.rs:33:7
+ --> $DIR/raw-keywords.rs:34:7
|
LL | #[cfg(r#raw)]
| ^^^^^
diff --git a/tests/ui/check-cfg/raw-keywords.rs b/tests/ui/check-cfg/raw-keywords.rs
index 5de1324..b82eb5a 100644
--- a/tests/ui/check-cfg/raw-keywords.rs
+++ b/tests/ui/check-cfg/raw-keywords.rs
@@ -6,7 +6,8 @@
//@ compile-flags: --cfg=true --cfg=async --check-cfg=cfg(r#true,r#async,edition2015,edition2021)
//
//@ revisions: edition2015 edition2021
-//@ [edition2021] compile-flags: --edition 2021
+//@ [edition2015] edition: 2015
+//@ [edition2021] edition: 2021
#[cfg(r#true)]
fn foo() {}
diff --git a/tests/ui/closures/2229_closure_analysis/issue-89606.rs b/tests/ui/closures/2229_closure_analysis/issue-89606.rs
index 8c88a4b..5494686 100644
--- a/tests/ui/closures/2229_closure_analysis/issue-89606.rs
+++ b/tests/ui/closures/2229_closure_analysis/issue-89606.rs
@@ -2,8 +2,8 @@
//
//@ check-pass
//@ revisions: twenty_eighteen twenty_twentyone
-//@ [twenty_eighteen]compile-flags: --edition 2018
-//@ [twenty_twentyone]compile-flags: --edition 2021
+//@ [twenty_eighteen] edition: 2018
+//@ [twenty_twentyone] edition: 2021
struct S<'a>(Option<&'a mut i32>);
diff --git a/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs
index 4fc2e6c..a771b81 100644
--- a/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs
+++ b/tests/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ revisions: twenty_eighteen twenty_twentyone
-//@ [twenty_eighteen]compile-flags: --edition 2018
-//@ [twenty_twentyone]compile-flags: --edition 2021
+//@ [twenty_eighteen] edition: 2018
+//@ [twenty_twentyone] edition: 2021
#[derive(Debug)]
struct Dropable(&'static str);
diff --git a/tests/ui/compiletest-self-test/trim-env-name.rs b/tests/ui/compiletest-self-test/trim-env-name.rs
new file mode 100644
index 0000000..0cb6efe
--- /dev/null
+++ b/tests/ui/compiletest-self-test/trim-env-name.rs
@@ -0,0 +1,23 @@
+//@ edition: 2024
+//@ revisions: set unset
+//@ run-pass
+//@ ignore-cross-compile (assume that non-cross targets have working env vars)
+//@ rustc-env: MY_RUSTC_ENV = my-rustc-value
+//@ exec-env: MY_EXEC_ENV = my-exec-value
+//@[unset] unset-rustc-env: MY_RUSTC_ENV
+//@[unset] unset-exec-env: MY_EXEC_ENV
+
+// Check that compiletest trims whitespace from environment variable names
+// specified in `rustc-env` and `exec-env` directives, so that
+// `//@ exec-env: FOO=bar` sees the name as `FOO` and not ` FOO`.
+//
+// Values are currently not trimmed.
+//
+// Since this is a compiletest self-test, only run it on non-cross targets,
+// to avoid having to worry about weird targets that don't support env vars.
+
+fn main() {
+ let is_set = cfg!(set);
+ assert_eq!(option_env!("MY_RUSTC_ENV"), is_set.then_some(" my-rustc-value"));
+ assert_eq!(std::env::var("MY_EXEC_ENV").ok().as_deref(), is_set.then_some(" my-exec-value"));
+}
diff --git a/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs b/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
index 2ac57f3..7753b7d 100644
--- a/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
+++ b/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
@@ -1,6 +1,6 @@
//@ revisions: edition2015 edition2021
-//@ [edition2015]compile-flags: --edition=2015
-//@ [edition2021]compile-flags: --edition=2021
+//@ [edition2015] edition: 2015
+//@ [edition2021] edition: 2021
#![feature(extern_types)]
#![feature(cfg_accessible)]
diff --git a/tests/ui/const-generics/generic_arg_infer/parend_infer.nogate.stderr b/tests/ui/const-generics/generic_arg_infer/parend_infer.nogate.stderr
new file mode 100644
index 0000000..d0a5da9
--- /dev/null
+++ b/tests/ui/const-generics/generic_arg_infer/parend_infer.nogate.stderr
@@ -0,0 +1,53 @@
+error[E0658]: const arguments cannot yet be inferred with `_`
+ --> $DIR/parend_infer.rs:24:16
+ |
+LL | let c: Foo<_> = Foo::<1>;
+ | ^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` 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[E0658]: const arguments cannot yet be inferred with `_`
+ --> $DIR/parend_infer.rs:26:16
+ |
+LL | let c: Foo<(_)> = Foo::<1>;
+ | ^^^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` 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[E0658]: const arguments cannot yet be inferred with `_`
+ --> $DIR/parend_infer.rs:28:16
+ |
+LL | let c: Foo<(((_)))> = Foo::<1>;
+ | ^^^^^^^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` 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[E0658]: using `_` for array lengths is unstable
+ --> $DIR/parend_infer.rs:17:17
+ |
+LL | let b: [u8; (_)] = [1; (((((_)))))];
+ | ^^^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` 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[E0658]: using `_` for array lengths is unstable
+ --> $DIR/parend_infer.rs:17:28
+ |
+LL | let b: [u8; (_)] = [1; (((((_)))))];
+ | ^^^^^^^^^^^
+ |
+ = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+ = help: add `#![feature(generic_arg_infer)]` 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 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/const-generics/generic_arg_infer/parend_infer.rs b/tests/ui/const-generics/generic_arg_infer/parend_infer.rs
index 81c4218..3dc27a7 100644
--- a/tests/ui/const-generics/generic_arg_infer/parend_infer.rs
+++ b/tests/ui/const-generics/generic_arg_infer/parend_infer.rs
@@ -1,7 +1,9 @@
-//@ check-pass
+//@[gate] check-pass
//@ revisions: gate nogate
#![cfg_attr(gate, feature(generic_arg_infer))]
+struct Foo<const N: usize>;
+
fn main() {
// AST Types preserve parens for pretty printing reasons. This means
// that this is parsed as a `TyKind::Paren(TyKind::Infer)`. Generic
@@ -9,4 +11,20 @@ fn main() {
// but `TyKind::Infer` wrapped in arbitrarily many `TyKind::Paren`.
let a: Vec<(_)> = vec![1_u8];
let a: Vec<(((((_)))))> = vec![1_u8];
+
+ // AST Exprs similarly preserve parens for pretty printing reasons.
+ #[rustfmt::skip]
+ let b: [u8; (_)] = [1; (((((_)))))];
+ //[nogate]~^ error: using `_` for array lengths is unstable
+ //[nogate]~| error: using `_` for array lengths is unstable
+ let b: [u8; 2] = b;
+
+ // This is the same case as AST types as the parser doesn't distinguish between const
+ // and type args when they share syntax
+ let c: Foo<_> = Foo::<1>;
+ //[nogate]~^ error: const arguments cannot yet be inferred with `_`
+ let c: Foo<(_)> = Foo::<1>;
+ //[nogate]~^ error: const arguments cannot yet be inferred with `_`
+ let c: Foo<(((_)))> = Foo::<1>;
+ //[nogate]~^ error: const arguments cannot yet be inferred with `_`
}
diff --git a/tests/ui/consts/const-suggest-feature.rs b/tests/ui/consts/const-suggest-feature.rs
index 0c94036..dbb166d 100644
--- a/tests/ui/consts/const-suggest-feature.rs
+++ b/tests/ui/consts/const-suggest-feature.rs
@@ -1,4 +1,4 @@
-//@compile-flags: --edition 2018
+//@ edition: 2018
use std::cell::Cell;
const WRITE: () = unsafe {
diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
index d6f0799..8f2bcd8 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
+++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![unstable(feature = "humans",
reason = "who ever let humans program computers,
we're apparently really bad at it",
diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr
index 2f3a653..aad3d76 100644
--- a/tests/ui/consts/missing_span_in_backtrace.stderr
+++ b/tests/ui/consts/missing_span_in_backtrace.stderr
@@ -12,10 +12,10 @@
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
note: inside `swap_nonoverlapping::compiletime::<MaybeUninit<u8>>`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::swap_nonoverlapping_simple_untyped::<MaybeUninit<u8>>`
+note: inside `std::ptr::swap_nonoverlapping_const::<MaybeUninit<u8>>`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::read::<MaybeUninit<MaybeUninit<u8>>>`
- --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `copy_nonoverlapping::<MaybeUninit<u8>>`
+ --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs
index ccf63f8..d60fe7d 100644
--- a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs
+++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs
@@ -16,7 +16,7 @@ impl Bar for Foo<'_> {
const STATIC: &str = "";
//~^ ERROR `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out
- //~| ERROR lifetime parameters or bounds on const `STATIC` do not match the trait declaration
+ //~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
}
fn main() {}
diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
index 33873f5..bb8365b 100644
--- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
+++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
@@ -39,14 +39,14 @@
LL | const STATIC: &'static str = "";
| +++++++
-error[E0195]: lifetime parameters or bounds on const `STATIC` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
--> $DIR/elided-lifetime.rs:16:17
|
LL | const STATIC: &str;
- | - lifetimes in impl do not match this const in trait
+ | - lifetimes in impl do not match this associated const in trait
...
LL | const STATIC: &str = "";
- | ^ lifetimes do not match const in trait
+ | ^ lifetimes do not match associated const in trait
error: aborting due to 3 previous errors
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
index 1e12259..85746df 100644
--- a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
@@ -9,7 +9,7 @@ impl Bar<'_> for A {
const STATIC: &str = "";
//~^ ERROR `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out
- //~| ERROR lifetime parameters or bounds on const `STATIC` do not match the trait declaration
+ //~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
}
struct B;
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
index 116f28e..38d24db 100644
--- a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
@@ -21,14 +21,14 @@
LL | const STATIC: &'static str = "";
| +++++++
-error[E0195]: lifetime parameters or bounds on const `STATIC` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration
--> $DIR/static-trait-impl.rs:9:17
|
LL | const STATIC: &'a str;
- | - lifetimes in impl do not match this const in trait
+ | - lifetimes in impl do not match this associated const in trait
...
LL | const STATIC: &str = "";
- | ^ lifetimes do not match const in trait
+ | ^ lifetimes do not match associated const in trait
error: aborting due to 2 previous errors
diff --git a/tests/ui/coroutine/async-gen-deduce-yield.rs b/tests/ui/coroutine/async-gen-deduce-yield.rs
index f85e4a5..a9572ee 100644
--- a/tests/ui/coroutine/async-gen-deduce-yield.rs
+++ b/tests/ui/coroutine/async-gen-deduce-yield.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024
+//@ edition: 2024
//@ check-pass
#![feature(async_iterator, gen_blocks)]
diff --git a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
index 583820c..53e3ce7 100644
--- a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
+++ b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024
+//@ edition: 2024
//@ check-pass
#![feature(async_iterator, gen_blocks)]
diff --git a/tests/ui/debuginfo/issue-105386-debuginfo-ub.rs b/tests/ui/debuginfo/issue-105386-debuginfo-ub.rs
index 7b850f3..e926a33 100644
--- a/tests/ui/debuginfo/issue-105386-debuginfo-ub.rs
+++ b/tests/ui/debuginfo/issue-105386-debuginfo-ub.rs
@@ -1,5 +1,6 @@
//@ run-pass
-//@ compile-flags: --edition 2021 -Copt-level=3 -Cdebuginfo=2 -Zmir-opt-level=3
+//@ compile-flags: -Copt-level=3 -Cdebuginfo=2 -Zmir-opt-level=3
+//@ edition: 2021
fn main() {
TranslatorI.visit_pre();
diff --git a/tests/ui/deprecation/try-macro-suggestion.rs b/tests/ui/deprecation/try-macro-suggestion.rs
index 1e477ab..0775f00 100644
--- a/tests/ui/deprecation/try-macro-suggestion.rs
+++ b/tests/ui/deprecation/try-macro-suggestion.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
fn foo() -> Result<(), ()> {
Ok(try!()); //~ ERROR use of deprecated `try` macro
Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
index 90bb715..6170250 100644
--- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
@@ -1,12 +1,14 @@
-error[E0277]: the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
+error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied
--> $DIR/as_expression.rs:56:21
|
LL | SelectInt.check("bar");
- | ----- ^^^^^ the trait `AsExpression<<SelectInt as Expression>::SqlType>` is not implemented for `&str`
+ | ----- ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str`
| |
| required by a bound introduced by this call
|
- = help: the trait `AsExpression<Text>` is implemented for `&str`
+ = help: the trait `AsExpression<Integer>` is not implemented for `&str`
+ but trait `AsExpression<Text>` is implemented for it
+ = help: for that trait implementation, expected `Text`, found `Integer`
note: required by a bound in `Foo::check`
--> $DIR/as_expression.rs:47:12
|
@@ -16,11 +18,11 @@
LL | T: AsExpression<Self::SqlType>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check`
-error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
+error[E0271]: type mismatch resolving `Integer == Text`
--> $DIR/as_expression.rs:56:5
|
LL | SelectInt.check("bar");
- | ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer`
+ | ^^^^^^^^^^^^^^^^^^^^^^ types differ
error: aborting due to 2 previous errors
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs
index b5ff768..673adb8 100644
--- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs
@@ -54,7 +54,6 @@ impl<T> Foo for T where T: Expression {}
fn main() {
SelectInt.check("bar");
- //[current]~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
- //[next]~^^ ERROR the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
+ //~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
//[next]~| ERROR type mismatch
}
diff --git a/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs b/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs
new file mode 100644
index 0000000..e2e9820
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs
@@ -0,0 +1,35 @@
+#![feature(ergonomic_clones)]
+#![allow(incomplete_features)]
+
+use std::clone::UseCloned;
+
+fn takes_val<T>(_: T) {}
+fn takes_ref<'a, T>(_: &'a T) {}
+
+#[derive(Clone)]
+struct Inner<'a, T>(&'a T);
+
+impl<'a, T> UseCloned for Inner<'a, T> where T: Clone {}
+
+fn main() {
+ let v = String::new();
+ let inner = Inner(&v);
+
+ let _ = use || {
+ takes_ref(inner.0);
+ takes_val(inner.0)
+ };
+ let _ = use || {
+ takes_ref(inner.0);
+ takes_val(inner.0);
+ takes_val(inner.0);
+ takes_val(inner)
+ };
+ let _ = use || {
+ takes_ref(inner.0);
+ takes_val(inner.0);
+ takes_val(inner);
+ takes_val(inner)
+ //~^ ERROR: use of moved value: `inner` [E0382]
+ };
+}
diff --git a/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr b/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr
new file mode 100644
index 0000000..7b25ca9
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `inner`
+ --> $DIR/multiple-use-variants.rs:32:19
+ |
+LL | takes_val(inner);
+ | ----- value moved here
+LL | takes_val(inner)
+ | ^^^^^ value used here after move
+ |
+ = note: move occurs because `inner` has type `Inner<'_, String>`, which does not implement the `Copy` trait
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed b/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed
new file mode 100644
index 0000000..fa83b53
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed
@@ -0,0 +1,26 @@
+//@ run-rustfix
+//@ edition:2018
+//@ check-pass
+#![feature(ergonomic_clones)]
+#![warn(rust_2021_compatibility)]
+#![allow(incomplete_features)]
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+ fn drop(&mut self) {
+ println!("{:?} dropped", self.0);
+ }
+}
+
+fn main() {
+ let a = (Foo(0), Foo(1));
+ let f = use || {
+ let _ = &a;
+ //~^ HELP: add a dummy
+ //~| WARNING: drop order
+ let x = a.0;
+ println!("{:?}", x);
+ };
+ f();
+}
diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs b/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs
new file mode 100644
index 0000000..4070e5c
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs
@@ -0,0 +1,25 @@
+//@ run-rustfix
+//@ edition:2018
+//@ check-pass
+#![feature(ergonomic_clones)]
+#![warn(rust_2021_compatibility)]
+#![allow(incomplete_features)]
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+ fn drop(&mut self) {
+ println!("{:?} dropped", self.0);
+ }
+}
+
+fn main() {
+ let a = (Foo(0), Foo(1));
+ let f = use || {
+ //~^ HELP: add a dummy
+ //~| WARNING: drop order
+ let x = a.0;
+ println!("{:?}", x);
+ };
+ f();
+}
diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr
new file mode 100644
index 0000000..b980be6
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr
@@ -0,0 +1,27 @@
+warning: changes to closure capture in Rust 2021 will affect drop order
+ --> $DIR/rfc2229-migration.rs:18:13
+ |
+LL | let f = use || {
+ | ^^^^^^
+...
+LL | let x = a.0;
+ | --- in Rust 2018, this closure captures all of `a`, but in Rust 2021, it will only capture `a.0`
+...
+LL | }
+ | - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
+ |
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+note: the lint level is defined here
+ --> $DIR/rfc2229-migration.rs:5:9
+ |
+LL | #![warn(rust_2021_compatibility)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ = note: `#[warn(rust_2021_incompatible_closure_captures)]` implied by `#[warn(rust_2021_compatibility)]`
+help: add a dummy let to cause `a` to be fully captured
+ |
+LL ~ let f = use || {
+LL + let _ = &a;
+ |
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr
new file mode 100644
index 0000000..ac8e1c5
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr
@@ -0,0 +1,28 @@
+error[E0382]: use of moved value: `x`
+ --> $DIR/spawn-thread.rs:15:42
+ |
+LL | let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
+ | - move occurs because `x` has type `(Arc<String>, Arc<Vec<i32>>, Arc<i32>)`, which does not implement the `Copy` trait
+LL | for _ in 0..10 {
+ | -------------- inside of this loop
+LL | let handler = std::thread::spawn(use || {
+ | __________________________________________-^^^^^
+LL | |
+LL | | drop((x.0, x.1, x.2));
+ | | --- use occurs due to use in closure
+LL | | });
+ | |_________- value moved here, in previous iteration of loop
+ |
+help: consider moving the expression out of the loop so it is only moved once
+ |
+LL ~ let mut value = std::thread::spawn(use || {
+LL +
+LL + drop((x.0, x.1, x.2));
+LL + });
+LL ~ for _ in 0..10 {
+LL ~ let handler = value;
+ |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.rs b/tests/ui/ergonomic-clones/closure/spawn-thread.rs
new file mode 100644
index 0000000..289d446
--- /dev/null
+++ b/tests/ui/ergonomic-clones/closure/spawn-thread.rs
@@ -0,0 +1,50 @@
+//@ revisions: edition2018 edition2024
+//@ [edition2018] edition: 2018
+//@ [edition2024] edition: 2024
+//@ [edition2024] check-pass
+
+#![feature(ergonomic_clones)]
+#![allow(incomplete_features)]
+
+use std::sync::Arc;
+
+fn foo() {
+ // The type is a tuple and doesn't implement UseCloned
+ let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
+ for _ in 0..10 {
+ let handler = std::thread::spawn(use || {
+ //[edition2018]~^ ERROR use of moved value: `x` [E0382]
+ drop((x.0, x.1, x.2));
+ });
+ handler.join().unwrap();
+ }
+}
+
+fn bar() {
+ let x = Arc::new("foo".to_owned());
+ let y = Arc::new(vec![1, 2, 3]);
+ let z = Arc::new(1);
+
+ for _ in 0..10 {
+ let handler = std::thread::spawn(use || {
+ drop((x, y, z));
+ });
+ handler.join().unwrap();
+ }
+}
+
+fn baz() {
+ use std::sync::Arc;
+ use std::thread;
+
+ let five = Arc::new(5);
+
+ for _ in 0..10 {
+ let handler = thread::spawn(use || {
+ println!("{five:?}");
+ });
+ handler.join().unwrap();
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/ergonomic-clones/dotuse/block.rs b/tests/ui/ergonomic-clones/dotuse/block.rs
new file mode 100644
index 0000000..2e423c6
--- /dev/null
+++ b/tests/ui/ergonomic-clones/dotuse/block.rs
@@ -0,0 +1,11 @@
+//@ check-pass
+
+#![feature(ergonomic_clones)]
+#![allow(incomplete_features)]
+
+fn use_block_test(x: i32) -> i32 {
+ let x = { let x = x + 1; x }.use;
+ x
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0622.rs b/tests/ui/error-codes/E0622.rs
deleted file mode 100644
index 0c2a4f2..0000000
--- a/tests/ui/error-codes/E0622.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![feature(intrinsics)]
-
-extern "C" {
-
- #[rustc_intrinsic]
- pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
- //~^ ERROR intrinsic must be a function [E0622]
-}
-
-fn main() {
- unsafe {
- atomic_singlethreadfence_seqcst();
- }
-}
diff --git a/tests/ui/error-codes/E0622.stderr b/tests/ui/error-codes/E0622.stderr
deleted file mode 100644
index c0aea54..0000000
--- a/tests/ui/error-codes/E0622.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0622]: intrinsic must be a function
- --> $DIR/E0622.rs:6:5
- |
-LL | pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0622`.
diff --git a/tests/ui/feature-gates/feature-gate-try_blocks.rs b/tests/ui/feature-gates/feature-gate-try_blocks.rs
index f565dd0..9081629 100644
--- a/tests/ui/feature-gates/feature-gate-try_blocks.rs
+++ b/tests/ui/feature-gates/feature-gate-try_blocks.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
pub fn main() {
let try_result: Option<_> = try { //~ ERROR `try` expression is experimental
diff --git a/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs b/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
index 33fda82..a32ebed 100644
--- a/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
+++ b/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2021
+//@ edition: 2021
pub fn demo() -> Option<i32> {
#[cfg(FALSE)]
diff --git a/tests/ui/feature-gates/feature-gate-yeet_expr.rs b/tests/ui/feature-gates/feature-gate-yeet_expr.rs
index 12cc17e..6604f49 100644
--- a/tests/ui/feature-gates/feature-gate-yeet_expr.rs
+++ b/tests/ui/feature-gates/feature-gate-yeet_expr.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
pub fn demo() -> Option<i32> {
do yeet //~ ERROR `do yeet` expression is experimental
diff --git a/tests/ui/generic-associated-types/const_params_have_right_type.stderr b/tests/ui/generic-associated-types/const_params_have_right_type.stderr
index 7899211..a3d3a66 100644
--- a/tests/ui/generic-associated-types/const_params_have_right_type.stderr
+++ b/tests/ui/generic-associated-types/const_params_have_right_type.stderr
@@ -1,4 +1,4 @@
-error[E0053]: type `Foo` has an incompatible generic parameter for trait `Trait`
+error[E0053]: associated type `Foo` has an incompatible generic parameter for trait `Trait`
--> $DIR/const_params_have_right_type.rs:6:14
|
LL | trait Trait {
diff --git a/tests/ui/generic-associated-types/issue-102114.current.stderr b/tests/ui/generic-associated-types/issue-102114.current.stderr
index 03471d0..5aace1e 100644
--- a/tests/ui/generic-associated-types/issue-102114.current.stderr
+++ b/tests/ui/generic-associated-types/issue-102114.current.stderr
@@ -1,4 +1,4 @@
-error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/issue-102114.rs:15:12
|
LL | type B<'b>;
diff --git a/tests/ui/generic-associated-types/issue-102114.next.stderr b/tests/ui/generic-associated-types/issue-102114.next.stderr
index 03471d0..5aace1e 100644
--- a/tests/ui/generic-associated-types/issue-102114.next.stderr
+++ b/tests/ui/generic-associated-types/issue-102114.next.stderr
@@ -1,4 +1,4 @@
-error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/issue-102114.rs:15:12
|
LL | type B<'b>;
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs
index c138102..a39a7aa 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs
@@ -12,11 +12,11 @@ trait Foo {
impl Foo for Fooy {
type A = u32;
- //~^ ERROR lifetime parameters or bounds on type `A` do not match the trait declaration
+ //~^ ERROR lifetime parameters or bounds on associated type `A` do not match the trait declaration
type B<'a, T> = Vec<T>;
//~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
type C<'a> = u32;
- //~^ ERROR lifetime parameters or bounds on type `C` do not match the trait declaration
+ //~^ ERROR lifetime parameters or bounds on associated type `C` do not match the trait declaration
}
struct Fooer;
@@ -25,7 +25,7 @@ impl Foo for Fooer {
type A<T> = u32;
//~^ ERROR type `A` has 1 type parameter but its trait declaration has 0 type parameters
type B<'a> = u32;
- //~^ ERROR lifetime parameters or bounds on type `B` do not match the trait declaration
+ //~^ ERROR lifetime parameters or bounds on associated type `B` do not match the trait declaration
type C<T> = T;
//~^ ERROR type `C` has 1 type parameter but its trait declaration has 0 type parameters
}
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
index fdd6d30..f7c4a07 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
@@ -1,13 +1,13 @@
-error[E0195]: lifetime parameters or bounds on type `A` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated type `A` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:14:11
|
LL | type A<'a>;
- | ---- lifetimes in impl do not match this type in trait
+ | ---- lifetimes in impl do not match this associated type in trait
...
LL | type A = u32;
- | ^ lifetimes do not match type in trait
+ | ^ lifetimes do not match associated type in trait
-error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `B` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:16:12
|
LL | type B<'a, 'b>;
@@ -20,16 +20,16 @@
| |
| found 1 type parameter
-error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated type `C` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:18:11
|
LL | type C;
- | - lifetimes in impl do not match this type in trait
+ | - lifetimes in impl do not match this associated type in trait
...
LL | type C<'a> = u32;
- | ^^^^ lifetimes do not match type in trait
+ | ^^^^ lifetimes do not match associated type in trait
-error[E0049]: type `A` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `A` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:25:12
|
LL | type A<'a>;
@@ -38,16 +38,16 @@
LL | type A<T> = u32;
| ^ found 1 type parameter
-error[E0195]: lifetime parameters or bounds on type `B` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated type `B` do not match the trait declaration
--> $DIR/parameter_number_and_kind_impl.rs:27:11
|
LL | type B<'a, 'b>;
- | -------- lifetimes in impl do not match this type in trait
+ | -------- lifetimes in impl do not match this associated type in trait
...
LL | type B<'a> = u32;
- | ^^^^ lifetimes do not match type in trait
+ | ^^^^ lifetimes do not match associated type in trait
-error[E0049]: type `C` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `C` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/parameter_number_and_kind_impl.rs:29:12
|
LL | type C;
diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs
index 0c94a42..dde47cf 100644
--- a/tests/ui/generic-const-items/assoc-const-missing-type.rs
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs
@@ -14,7 +14,7 @@ impl Trait for () {
//~| ERROR mismatched types
const Q = "";
//~^ ERROR missing type for `const` item
- //~| ERROR lifetime parameters or bounds on const `Q` do not match the trait declaration
+ //~| ERROR lifetime parameters or bounds on associated const `Q` do not match the trait declaration
}
fn main() {}
diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr
index 5af119d..9f6db57 100644
--- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr
@@ -15,14 +15,14 @@
LL | const K<T> = ();
| ^ help: provide a type for the associated constant: `()`
-error[E0195]: lifetime parameters or bounds on const `Q` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated const `Q` do not match the trait declaration
--> $DIR/assoc-const-missing-type.rs:15:12
|
LL | const Q<'a>: &'a str;
- | ---- lifetimes in impl do not match this const in trait
+ | ---- lifetimes in impl do not match this associated const in trait
...
LL | const Q = "";
- | ^ lifetimes do not match const in trait
+ | ^ lifetimes do not match associated const in trait
error: missing type for `const` item
--> $DIR/assoc-const-missing-type.rs:15:12
diff --git a/tests/ui/generic-const-items/compare-impl-item.rs b/tests/ui/generic-const-items/compare-impl-item.rs
index 21c958a..b301cd0 100644
--- a/tests/ui/generic-const-items/compare-impl-item.rs
+++ b/tests/ui/generic-const-items/compare-impl-item.rs
@@ -22,7 +22,7 @@ impl<P> Trait<P> for () {
const D<const N: u16>: u16 = N;
//~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
const E: &'static () = &();
- //~^ ERROR lifetime parameters or bounds on const `E` do not match the trait declaration
+ //~^ ERROR lifetime parameters or bounds on associated const `E` do not match the trait declaration
const F: usize = 1024
where
diff --git a/tests/ui/generic-const-items/compare-impl-item.stderr b/tests/ui/generic-const-items/compare-impl-item.stderr
index 3bf28e9..f7e3ff6 100644
--- a/tests/ui/generic-const-items/compare-impl-item.stderr
+++ b/tests/ui/generic-const-items/compare-impl-item.stderr
@@ -1,4 +1,4 @@
-error[E0049]: const `A` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated const `A` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/compare-impl-item.rs:16:13
|
LL | const A: ();
@@ -7,7 +7,7 @@
LL | const A<T>: () = ();
| ^ found 1 type parameter
-error[E0049]: const `B` has 1 const parameter but its trait declaration has 2 const parameters
+error[E0049]: associated const `B` has 1 const parameter but its trait declaration has 2 const parameters
--> $DIR/compare-impl-item.rs:18:13
|
LL | const B<const K: u64, const Q: u64>: u64;
@@ -18,7 +18,7 @@
LL | const B<const K: u64>: u64 = 0;
| ^^^^^^^^^^^^ found 1 const parameter
-error[E0049]: const `C` has 0 type parameters but its trait declaration has 1 type parameter
+error[E0049]: associated const `C` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/compare-impl-item.rs:20:13
|
LL | const C<T>: T;
@@ -27,7 +27,7 @@
LL | const C<'a>: &'a str = "";
| ^^ found 0 type parameters
-error[E0053]: const `D` has an incompatible generic parameter for trait `Trait`
+error[E0053]: associated const `D` has an incompatible generic parameter for trait `Trait`
--> $DIR/compare-impl-item.rs:22:13
|
LL | trait Trait<P> {
@@ -42,14 +42,14 @@
LL | const D<const N: u16>: u16 = N;
| ^^^^^^^^^^^^ found const parameter of type `u16`
-error[E0195]: lifetime parameters or bounds on const `E` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated const `E` do not match the trait declaration
--> $DIR/compare-impl-item.rs:24:12
|
LL | const E<'a>: &'a ();
- | ---- lifetimes in impl do not match this const in trait
+ | ---- lifetimes in impl do not match this associated const in trait
...
LL | const E: &'static () = &();
- | ^ lifetimes do not match const in trait
+ | ^ lifetimes do not match associated const in trait
error[E0276]: impl has stricter requirements than trait
--> $DIR/compare-impl-item.rs:29:12
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr
index 7b9fd6b..c839457 100644
--- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr
@@ -13,7 +13,7 @@
| ^^^^^^^^^^^^^
error[E0308]: mismatched types
- --> $DIR/candidate-from-env-universe-err-project.rs:53:30
+ --> $DIR/candidate-from-env-universe-err-project.rs:52:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -22,7 +22,7 @@
found associated type `<T as Trait<'a>>::Assoc`
error[E0308]: mismatched types
- --> $DIR/candidate-from-env-universe-err-project.rs:53:30
+ --> $DIR/candidate-from-env-universe-err-project.rs:52:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr
index 6e0ec56..468dc3b 100644
--- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr
@@ -22,38 +22,20 @@
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound`
-error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
- --> $DIR/candidate-from-env-universe-err-project.rs:38:24
- |
-LL | projection_bound::<T>();
- | ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
- |
-note: types differ
- --> $DIR/candidate-from-env-universe-err-project.rs:14:18
- |
-LL | type Assoc = usize;
- | ^^^^^
-note: required by a bound in `projection_bound`
- --> $DIR/candidate-from-env-universe-err-project.rs:18:42
- |
-LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
- | ^^^^^^^^^^^^^ required by this bound in `projection_bound`
-
error: higher-ranked subtype error
- --> $DIR/candidate-from-env-universe-err-project.rs:53:30
+ --> $DIR/candidate-from-env-universe-err-project.rs:52:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
- --> $DIR/candidate-from-env-universe-err-project.rs:53:30
+ --> $DIR/candidate-from-env-universe-err-project.rs:52:30
|
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
index a77d87f..d70e392 100644
--- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
@@ -36,9 +36,8 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
// does not use the leak check when trying the where-bound, causing us
// to prefer it over the impl, resulting in a placeholder error.
projection_bound::<T>();
- //[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
- //[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
- //[current]~^^^ ERROR mismatched types
+ //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
+ //[current]~^^ ERROR mismatched types
}
fn function3<T: Trait<'static, Assoc = usize>>() {
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95034.rs b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs
index 53b28c2..f334697 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-95034.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs
@@ -1,5 +1,6 @@
//@ check-pass
-//@ compile-flags: --edition=2021 --crate-type=lib
+//@ compile-flags: --crate-type=lib
+//@ edition: 2021
use std::{
future::Future,
diff --git a/tests/ui/impl-trait/auto-trait-contains-err.rs b/tests/ui/impl-trait/auto-trait-contains-err.rs
index d7f0942..8a2ebe3 100644
--- a/tests/ui/impl-trait/auto-trait-contains-err.rs
+++ b/tests/ui/impl-trait/auto-trait-contains-err.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
use std::future::Future;
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
index c76415d..341262a 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
@@ -4,7 +4,7 @@
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
-error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
+error[E0049]: associated type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
|
LL | type LineStream<'a, Repr>
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
index 4d72490..9632d2c 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
@@ -4,7 +4,7 @@
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
-error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
+error[E0049]: associated type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
|
LL | type LineStream<'a, Repr>
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
index ab21dae..7dc747b 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
@@ -8,7 +8,7 @@
impl<'a, I: 'a + Iterable> Iterable for &'a I {
type Item = u32;
- //~^ ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration
+ //~^ ERROR lifetime parameters or bounds on associated type `Item` do not match the trait declaration
fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
//~^ ERROR binding for associated type `Item` references lifetime `'missing`
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
index d8a2eef..eaa3204 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
@@ -12,17 +12,17 @@
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated type `Item` do not match the trait declaration
--> $DIR/span-bug-issue-121457.rs:10:14
|
LL | type Item<'a>
- | ---- lifetimes in impl do not match this type in trait
+ | ---- lifetimes in impl do not match this associated type in trait
LL | where
LL | Self: 'a;
| -- this bound might be missing in the impl
...
LL | type Item = u32;
- | ^ lifetimes do not match type in trait
+ | ^ lifetimes do not match associated type in trait
error[E0277]: `()` is not an iterator
--> $DIR/span-bug-issue-121457.rs:13:23
diff --git a/tests/ui/imports/redundant-import-extern-prelude.rs b/tests/ui/imports/redundant-import-extern-prelude.rs
index 0064eaa..b573b8f 100644
--- a/tests/ui/imports/redundant-import-extern-prelude.rs
+++ b/tests/ui/imports/redundant-import-extern-prelude.rs
@@ -5,7 +5,8 @@
// See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
-//@ compile-flags: --extern aux_issue_121915 --edition 2018
+//@ compile-flags: --extern aux_issue_121915
+//@ edition: 2018
//@ aux-build: aux-issue-121915.rs
#[deny(redundant_imports)]
diff --git a/tests/ui/imports/redundant-import-extern-prelude.stderr b/tests/ui/imports/redundant-import-extern-prelude.stderr
index 6d2518c..06cce7e 100644
--- a/tests/ui/imports/redundant-import-extern-prelude.stderr
+++ b/tests/ui/imports/redundant-import-extern-prelude.stderr
@@ -1,11 +1,11 @@
error: the item `aux_issue_121915` is imported redundantly
- --> $DIR/redundant-import-extern-prelude.rs:14:9
+ --> $DIR/redundant-import-extern-prelude.rs:15:9
|
LL | use aux_issue_121915;
| ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by the extern prelude
|
note: the lint level is defined here
- --> $DIR/redundant-import-extern-prelude.rs:11:8
+ --> $DIR/redundant-import-extern-prelude.rs:12:8
|
LL | #[deny(redundant_imports)]
| ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.rs b/tests/ui/imports/redundant-import-issue-121915-2015.rs
index dc499bc..7108776 100644
--- a/tests/ui/imports/redundant-import-issue-121915-2015.rs
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --extern aux_issue_121915 --edition 2015
+//@ compile-flags: --extern aux_issue_121915
+//@ edition: 2015
//@ aux-build: aux-issue-121915.rs
extern crate aux_issue_121915;
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.stderr b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
index f4e9f60..367a4f1 100644
--- a/tests/ui/imports/redundant-import-issue-121915-2015.stderr
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
@@ -1,5 +1,5 @@
error: the item `aux_issue_121915` is imported redundantly
- --> $DIR/redundant-import-issue-121915-2015.rs:8:9
+ --> $DIR/redundant-import-issue-121915-2015.rs:9:9
|
LL | extern crate aux_issue_121915;
| ------------------------------ the item `aux_issue_121915` is already imported here
@@ -8,7 +8,7 @@
| ^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/redundant-import-issue-121915-2015.rs:6:8
+ --> $DIR/redundant-import-issue-121915-2015.rs:7:8
|
LL | #[deny(redundant_imports)]
| ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/imports/suggest-remove-issue-121315.rs b/tests/ui/imports/suggest-remove-issue-121315.rs
index ee3ceb6..3c036b8 100644
--- a/tests/ui/imports/suggest-remove-issue-121315.rs
+++ b/tests/ui/imports/suggest-remove-issue-121315.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2021
+//@ edition: 2021
#![deny(unused_imports, redundant_imports)]
#![allow(dead_code)]
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/invalid-compile-flags/crate-type-flag.rs
index 8ccce97..61b35cf 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.rs
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.rs
@@ -3,8 +3,6 @@
//!
//! This test does not try to check if the output artifacts are valid.
-// FIXME(#132309): add a proper `supports-crate-type` directive.
-
// Single valid crate types should pass
//@ revisions: lib rlib staticlib dylib cdylib bin proc_dash_macro
@@ -17,19 +15,18 @@
//@[staticlib] compile-flags: --crate-type=staticlib
//@[staticlib] check-pass
-//@[dylib] ignore-musl (dylib is supported, but musl libc is statically linked by default)
-//@[dylib] ignore-wasm (dylib is not supported)
+//@[dylib] needs-crate-type: dylib
//@[dylib] compile-flags: --crate-type=dylib
//@[dylib] check-pass
-//@[cdylib] ignore-musl (cdylib is supported, but musl libc is statically linked by default)
+//@[cdylib] needs-crate-type: cdylib
//@[cdylib] compile-flags: --crate-type=cdylib
//@[cdylib] check-pass
//@[bin] compile-flags: --crate-type=bin
//@[bin] check-pass
-//@[proc_dash_macro] ignore-wasm (proc-macro is not supported)
+//@[proc_dash_macro] needs-crate-type: proc-macro
//@[proc_dash_macro] needs-unwind (panic=abort causes warning to be emitted)
//@[proc_dash_macro] compile-flags: --crate-type=proc-macro
//@[proc_dash_macro] check-pass
diff --git a/tests/ui/label/label_break_value_desugared_break.rs b/tests/ui/label/label_break_value_desugared_break.rs
index b7e7fd4..17ef1ba 100644
--- a/tests/ui/label/label_break_value_desugared_break.rs
+++ b/tests/ui/label/label_break_value_desugared_break.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
//@ run-pass
diff --git a/tests/ui/let-else/issue-102317.rs b/tests/ui/let-else/issue-102317.rs
index d94410e..5afcacf 100644
--- a/tests/ui/let-else/issue-102317.rs
+++ b/tests/ui/let-else/issue-102317.rs
@@ -1,6 +1,7 @@
// issue #102317
//@ build-pass
-//@ compile-flags: --edition 2021 -C opt-level=3 -Zvalidate-mir
+//@ compile-flags: -C opt-level=3 -Zvalidate-mir
+//@ edition: 2021
struct SegmentJob;
diff --git a/tests/ui/lifetimes/issue-83737-binders-across-types.rs b/tests/ui/lifetimes/issue-83737-binders-across-types.rs
index d20c84d..6f39938 100644
--- a/tests/ui/lifetimes/issue-83737-binders-across-types.rs
+++ b/tests/ui/lifetimes/issue-83737-binders-across-types.rs
@@ -1,5 +1,5 @@
//@ build-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
//@ compile-flags: --crate-type rlib
use std::future::Future;
diff --git a/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs b/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs
index 466bcdc..dcc8c7e 100644
--- a/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs
+++ b/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs
@@ -1,5 +1,5 @@
//@ build-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
//@ compile-flags: --crate-type rlib
use std::future::Future;
diff --git a/tests/ui/lifetimes/no_lending_iterators.rs b/tests/ui/lifetimes/no_lending_iterators.rs
index 2139547..b3e8ad0 100644
--- a/tests/ui/lifetimes/no_lending_iterators.rs
+++ b/tests/ui/lifetimes/no_lending_iterators.rs
@@ -25,7 +25,7 @@ fn poke(&mut self, item: Self::Item) {
impl Bar for isize {
type Item<'a> = &'a isize;
- //~^ ERROR 27:14: 27:18: lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
+ //~^ ERROR 27:14: 27:18: lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195]
fn poke(&mut self, item: Self::Item) {
self += *item;
diff --git a/tests/ui/lifetimes/no_lending_iterators.stderr b/tests/ui/lifetimes/no_lending_iterators.stderr
index 9ceaef2..340ef93 100644
--- a/tests/ui/lifetimes/no_lending_iterators.stderr
+++ b/tests/ui/lifetimes/no_lending_iterators.stderr
@@ -16,14 +16,14 @@
LL | type Item = &usize;
| ^ this lifetime must come from the implemented type
-error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated type `Item` do not match the trait declaration
--> $DIR/no_lending_iterators.rs:27:14
|
LL | type Item;
- | - lifetimes in impl do not match this type in trait
+ | - lifetimes in impl do not match this associated type in trait
...
LL | type Item<'a> = &'a isize;
- | ^^^^ lifetimes do not match type in trait
+ | ^^^^ lifetimes do not match associated type in trait
error: aborting due to 3 previous errors
diff --git a/tests/ui/linkage-attr/issue-12133-3.rs b/tests/ui/linkage-attr/issue-12133-3.rs
index 473d577..df1b0b2 100644
--- a/tests/ui/linkage-attr/issue-12133-3.rs
+++ b/tests/ui/linkage-attr/issue-12133-3.rs
@@ -2,8 +2,7 @@
//@ aux-build:issue-12133-rlib.rs
//@ aux-build:issue-12133-dylib.rs
//@ aux-build:issue-12133-dylib2.rs
-//@ ignore-wasm32 no dylib support
-//@ ignore-musl
+//@ needs-crate-type: dylib
//@ needs-dynamic-linking
diff --git a/tests/ui/lint/large_assignments/inline_mir.rs b/tests/ui/lint/large_assignments/inline_mir.rs
new file mode 100644
index 0000000..fc27b8f
--- /dev/null
+++ b/tests/ui/lint/large_assignments/inline_mir.rs
@@ -0,0 +1,24 @@
+#![feature(large_assignments)]
+#![deny(large_assignments)]
+#![move_size_limit = "1000"]
+
+//! Tests that with `-Zinline-mir`, we do NOT get an error that points to the
+//! implementation of `UnsafeCell` since that is not actionable by the user:
+//!
+//! ```text
+//! error: moving 9999 bytes
+//! --> /rustc/FAKE_PREFIX/library/core/src/cell.rs:2054:9
+//! |
+//! = note: value moved from here
+//! ```
+//!
+//! We want the diagnostics to point to the relevant user code.
+
+//@ build-fail
+//@ compile-flags: -Zmir-opt-level=1 -Zinline-mir
+
+pub fn main() {
+ let data = [10u8; 9999];
+ let cell = std::cell::UnsafeCell::new(data); //~ ERROR large_assignments
+ std::hint::black_box(cell);
+}
diff --git a/tests/ui/lint/large_assignments/inline_mir.stderr b/tests/ui/lint/large_assignments/inline_mir.stderr
new file mode 100644
index 0000000..d9010e2
--- /dev/null
+++ b/tests/ui/lint/large_assignments/inline_mir.stderr
@@ -0,0 +1,15 @@
+error: moving 9999 bytes
+ --> $DIR/inline_mir.rs:22:16
+ |
+LL | let cell = std::cell::UnsafeCell::new(data);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
+ |
+ = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
+note: the lint level is defined here
+ --> $DIR/inline_mir.rs:2:9
+ |
+LL | #![deny(large_assignments)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
index 6f701cd..a63e9c5 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
@@ -10,28 +10,27 @@
// But should fire on non-binary crates.
-// FIXME(#132309): dylib crate type is not supported on wasm; we need a proper
-// supports-crate-type directive. Also, needs-dynamic-linking should rule out
-// musl since it supports neither dylibs nor cdylibs.
-//@[dylib_] ignore-wasm
-//@[dylib_] ignore-musl
-//@[cdylib_] ignore-musl
-
-//@[dylib_] needs-dynamic-linking
+//@[cdylib_] compile-flags: --crate-type=cdylib
//@[cdylib_] needs-dynamic-linking
+//@[cdylib_] needs-crate-type: cdylib
+
+//@[dylib_] compile-flags: --crate-type=dylib
+//@[dylib_] needs-dynamic-linking
+//@[dylib_] needs-crate-type: dylib
+
+//@[lib_] compile-flags: --crate-type=lib
+
//@[proc_macro_] force-host
//@[proc_macro_] no-prefer-dynamic
-
-//@[cdylib_] compile-flags: --crate-type=cdylib
-//@[dylib_] compile-flags: --crate-type=dylib
-//@[lib_] compile-flags: --crate-type=lib
//@[proc_macro_] compile-flags: --crate-type=proc-macro
-//@[rlib_] compile-flags: --crate-type=rlib
-//@[staticlib_] compile-flags: --crate-type=staticlib
-
-// The compiler may emit a warning that causes stderr output
-// that contains a warning this test does not wish to check.
+// The compiler may emit a warning that causes stderr output that contains a warning this test does
+// not wish to check.
//@[proc_macro_] needs-unwind
+//@[proc_macro_] needs-crate-type: proc-macro
+
+//@[rlib_] compile-flags: --crate-type=rlib
+
+//@[staticlib_] compile-flags: --crate-type=staticlib
#![crate_name = "NonSnakeCase"]
//[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
index 1192b69..a9c0188 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
@@ -1,11 +1,11 @@
error: crate `NonSnakeCase` should have a snake case name
- --> $DIR/lint-non-snake-case-crate.rs:36:18
+ --> $DIR/lint-non-snake-case-crate.rs:35:18
|
LL | #![crate_name = "NonSnakeCase"]
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
note: the lint level is defined here
- --> $DIR/lint-non-snake-case-crate.rs:38:9
+ --> $DIR/lint-non-snake-case-crate.rs:37:9
|
LL | #![deny(non_snake_case)]
| ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/unqualified_local_imports.rs b/tests/ui/lint/unqualified_local_imports.rs
index 9de7147..b7036f9 100644
--- a/tests/ui/lint/unqualified_local_imports.rs
+++ b/tests/ui/lint/unqualified_local_imports.rs
@@ -1,4 +1,4 @@
-//@compile-flags: --edition 2018
+//@ edition: 2018
#![feature(unqualified_local_imports)]
#![deny(unqualified_local_imports)]
diff --git a/tests/ui/lint/unused/issue-70041.rs b/tests/ui/lint/unused/issue-70041.rs
index 817dfe8..890ba37 100644
--- a/tests/ui/lint/unused/issue-70041.rs
+++ b/tests/ui/lint/unused/issue-70041.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2018
+//@ edition: 2018
//@ run-pass
macro_rules! regex {
diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.fixed b/tests/ui/macros/expr_2021_cargo_fix_edition.fixed
index 061a4b9..c0d2760 100644
--- a/tests/ui/macros/expr_2021_cargo_fix_edition.fixed
+++ b/tests/ui/macros/expr_2021_cargo_fix_edition.fixed
@@ -1,6 +1,6 @@
//@ run-rustfix
//@ check-pass
-//@ compile-flags: --edition=2021
+//@ edition: 2021
#![warn(edition_2024_expr_fragment_specifier)]
macro_rules! m {
diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.rs b/tests/ui/macros/expr_2021_cargo_fix_edition.rs
index cd9cd96..b2c16fc7 100644
--- a/tests/ui/macros/expr_2021_cargo_fix_edition.rs
+++ b/tests/ui/macros/expr_2021_cargo_fix_edition.rs
@@ -1,6 +1,6 @@
//@ run-rustfix
//@ check-pass
-//@ compile-flags: --edition=2021
+//@ edition: 2021
#![warn(edition_2024_expr_fragment_specifier)]
macro_rules! m {
diff --git a/tests/ui/mir/issue-105809.rs b/tests/ui/mir/issue-105809.rs
index e7a8fb6..a46dcf3 100644
--- a/tests/ui/mir/issue-105809.rs
+++ b/tests/ui/mir/issue-105809.rs
@@ -1,7 +1,8 @@
// Non-regression test ICE from issue #105809 and duplicates.
//@ build-pass: the ICE is during codegen
-//@ compile-flags: --edition 2018 -Zmir-opt-level=1
+//@ compile-flags: -Zmir-opt-level=1
+//@ edition: 2018
use std::{future::Future, pin::Pin};
diff --git a/tests/ui/mismatched_types/closure-mismatch.stderr b/tests/ui/mismatched_types/closure-mismatch.current.stderr
similarity index 90%
rename from tests/ui/mismatched_types/closure-mismatch.stderr
rename to tests/ui/mismatched_types/closure-mismatch.current.stderr
index 802110c..378fe83 100644
--- a/tests/ui/mismatched_types/closure-mismatch.stderr
+++ b/tests/ui/mismatched_types/closure-mismatch.current.stderr
@@ -1,5 +1,5 @@
error: implementation of `FnOnce` is not general enough
- --> $DIR/closure-mismatch.rs:8:5
+ --> $DIR/closure-mismatch.rs:12:5
|
LL | baz(|_| ());
| ^^^^^^^^^^^ implementation of `FnOnce` is not general enough
@@ -8,7 +8,7 @@
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
error: implementation of `Fn` is not general enough
- --> $DIR/closure-mismatch.rs:8:5
+ --> $DIR/closure-mismatch.rs:12:5
|
LL | baz(|_| ());
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
@@ -17,7 +17,7 @@
= note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
- --> $DIR/closure-mismatch.rs:11:5
+ --> $DIR/closure-mismatch.rs:16:5
|
LL | baz(|x| ());
| ^^^^^^^^^^^ implementation of `FnOnce` is not general enough
@@ -26,7 +26,7 @@
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
error: implementation of `Fn` is not general enough
- --> $DIR/closure-mismatch.rs:11:5
+ --> $DIR/closure-mismatch.rs:16:5
|
LL | baz(|x| ());
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
diff --git a/tests/ui/mismatched_types/closure-mismatch.next.stderr b/tests/ui/mismatched_types/closure-mismatch.next.stderr
new file mode 100644
index 0000000..6b4620a
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-mismatch.next.stderr
@@ -0,0 +1,67 @@
+error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}: Foo` is not satisfied
+ --> $DIR/closure-mismatch.rs:12:9
+ |
+LL | baz(|_| ());
+ | --- ^^^^^^ unsatisfied trait bound
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}`
+ = note: expected a closure with signature `for<'a> fn(&'a ())`
+ found a closure with signature `fn(&())`
+note: this is a known limitation of the trait solver that will be lifted in the future
+ --> $DIR/closure-mismatch.rs:12:9
+ |
+LL | baz(|_| ());
+ | ----^^^----
+ | | |
+ | | the trait solver is unable to infer the generic types that should be inferred from this argument
+ | add turbofish arguments to this call to specify the types manually, even if it's redundant
+note: required for `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` to implement `Foo`
+ --> $DIR/closure-mismatch.rs:7:18
+ |
+LL | impl<T: Fn(&())> Foo for T {}
+ | ------- ^^^ ^
+ | |
+ | unsatisfied trait bound introduced here
+note: required by a bound in `baz`
+ --> $DIR/closure-mismatch.rs:9:11
+ |
+LL | fn baz<T: Foo>(_: T) {}
+ | ^^^ required by this bound in `baz`
+
+error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}: Foo` is not satisfied
+ --> $DIR/closure-mismatch.rs:16:9
+ |
+LL | baz(|x| ());
+ | --- ^^^^^^ unsatisfied trait bound
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}`
+ = note: expected a closure with signature `for<'a> fn(&'a ())`
+ found a closure with signature `fn(&())`
+note: this is a known limitation of the trait solver that will be lifted in the future
+ --> $DIR/closure-mismatch.rs:16:9
+ |
+LL | baz(|x| ());
+ | ----^^^----
+ | | |
+ | | the trait solver is unable to infer the generic types that should be inferred from this argument
+ | add turbofish arguments to this call to specify the types manually, even if it's redundant
+note: required for `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` to implement `Foo`
+ --> $DIR/closure-mismatch.rs:7:18
+ |
+LL | impl<T: Fn(&())> Foo for T {}
+ | ------- ^^^ ^
+ | |
+ | unsatisfied trait bound introduced here
+note: required by a bound in `baz`
+ --> $DIR/closure-mismatch.rs:9:11
+ |
+LL | fn baz<T: Foo>(_: T) {}
+ | ^^^ required by this bound in `baz`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/mismatched_types/closure-mismatch.rs b/tests/ui/mismatched_types/closure-mismatch.rs
index efaed4d..1a24c76 100644
--- a/tests/ui/mismatched_types/closure-mismatch.rs
+++ b/tests/ui/mismatched_types/closure-mismatch.rs
@@ -1,3 +1,7 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
trait Foo {}
impl<T: Fn(&())> Foo for T {}
@@ -6,9 +10,11 @@ fn baz<T: Foo>(_: T) {}
fn main() {
baz(|_| ());
- //~^ ERROR implementation of `FnOnce` is not general enough
- //~| ERROR implementation of `Fn` is not general enough
+ //[current]~^ ERROR implementation of `FnOnce` is not general enough
+ //[current]~| ERROR implementation of `Fn` is not general enough
+ //[next]~^^^ ERROR Foo` is not satisfied
baz(|x| ());
- //~^ ERROR implementation of `FnOnce` is not general enough
- //~| ERROR implementation of `Fn` is not general enough
+ //[current]~^ ERROR implementation of `FnOnce` is not general enough
+ //[current]~| ERROR implementation of `Fn` is not general enough
+ //[next]~^^^ ERROR Foo` is not satisfied
}
diff --git a/tests/ui/no_std/simple-runs.rs b/tests/ui/no_std/simple-runs.rs
new file mode 100644
index 0000000..8931ac7
--- /dev/null
+++ b/tests/ui/no_std/simple-runs.rs
@@ -0,0 +1,41 @@
+//! Check that `no_std` binaries can link and run without depending on `libstd`.
+
+//@ run-pass
+//@ compile-flags: -Cpanic=abort
+//@ ignore-wasm different `main` convention
+
+#![no_std]
+#![no_main]
+
+use core::ffi::{c_char, c_int};
+use core::panic::PanicInfo;
+
+// # Linux
+//
+// Linking `libc` is required by crt1.o, otherwise the linker fails with:
+// > /usr/bin/ld: in function `_start': undefined reference to `__libc_start_main'
+//
+// # Apple
+//
+// Linking `libSystem` is required, otherwise the linker fails with:
+// > ld: dynamic executables or dylibs must link with libSystem.dylib
+//
+// With the new linker introduced in Xcode 15, the error is instead:
+// > Undefined symbols: "dyld_stub_binder", referenced from: <initial-undefines>
+//
+// This _can_ be worked around by raising the deployment target with
+// MACOSX_DEPLOYMENT_TARGET=13.0, though it's a bit hard to test that while
+// still allowing the test suite to support running with older Xcode versions.
+#[cfg_attr(all(not(target_vendor = "apple"), unix), link(name = "c"))]
+#[cfg_attr(target_vendor = "apple", link(name = "System"))]
+extern "C" {}
+
+#[panic_handler]
+fn panic_handler(_info: &PanicInfo<'_>) -> ! {
+ loop {}
+}
+
+#[no_mangle]
+extern "C" fn main(_argc: c_int, _argv: *const *const c_char) -> c_int {
+ 0
+}
diff --git a/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs b/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
index 8b78241..a691ceb 100644
--- a/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
+++ b/tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs
@@ -1,9 +1,7 @@
//@ build-fail
//@ compile-flags:-C panic=abort -C prefer-dynamic
//@ needs-unwind
-//@ ignore-musl - no dylibs here
-//@ ignore-emscripten
-//@ ignore-sgx no dynamic lib support
+//@ needs-crate-type: dylib
// This is a test where the local crate, compiled with `panic=abort`, links to
// the standard library **dynamically** which is already linked against
diff --git a/tests/ui/panic-runtime/two-panic-runtimes.rs b/tests/ui/panic-runtime/two-panic-runtimes.rs
index 15c08cb..7add07e 100644
--- a/tests/ui/panic-runtime/two-panic-runtimes.rs
+++ b/tests/ui/panic-runtime/two-panic-runtimes.rs
@@ -1,7 +1,6 @@
// ignore-tidy-linelength
//@ build-fail
-//@ compile-flags: --error-format=human
-//@ error-pattern: cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
+//@ dont-require-annotations:ERROR
//@ dont-check-compiler-stderr
//@ aux-build:panic-runtime-unwind.rs
//@ aux-build:panic-runtime-unwind2.rs
@@ -16,7 +15,8 @@
fn main() {}
-// FIXME: The second and third errors are target-dependent.
-//FIXME~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
+//~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
+// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
+// instead of `dont-require-annotations`.
//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind2` is not compiled with this crate's panic strategy `abort`
//FIXME~? ERROR the crate `panic_runtime_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind.rs b/tests/ui/panic-runtime/want-abort-got-unwind.rs
index ed61c26..1ae2e62 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind.rs
@@ -1,7 +1,6 @@
// ignore-tidy-linelength
//@ build-fail
-//@ compile-flags: --error-format=human
-//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+//@ dont-require-annotations:ERROR
//@ dont-check-compiler-stderr
//@ aux-build:panic-runtime-unwind.rs
//@ compile-flags:-C panic=abort
@@ -10,7 +9,8 @@
fn main() {}
-// FIXME: The first and third errors are target-dependent.
+//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
+// instead of `dont-require-annotations`.
//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
-//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind2.rs b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
index 504fd77..dc4d3ea 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind2.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
@@ -1,7 +1,6 @@
// ignore-tidy-linelength
//@ build-fail
-//@ compile-flags: --error-format=human
-//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+//@ dont-require-annotations:ERROR
//@ dont-check-compiler-stderr
//@ aux-build:panic-runtime-unwind.rs
//@ aux-build:wants-panic-runtime-unwind.rs
@@ -11,7 +10,8 @@
fn main() {}
-// FIXME: The first and third errors are target-dependent.
+//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
+// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
+// instead of `dont-require-annotations`.
//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
-//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/parser/impl-parsing-2.rs b/tests/ui/parser/impl-parsing-2.rs
new file mode 100644
index 0000000..7a71217
--- /dev/null
+++ b/tests/ui/parser/impl-parsing-2.rs
@@ -0,0 +1,4 @@
+impl ! {} // OK
+
+default unsafe FAIL //~ ERROR expected item, found keyword `unsafe`
+//~^ ERROR `default` is not followed by an item
diff --git a/tests/ui/parser/impl-parsing-2.stderr b/tests/ui/parser/impl-parsing-2.stderr
new file mode 100644
index 0000000..45e2c42
--- /dev/null
+++ b/tests/ui/parser/impl-parsing-2.stderr
@@ -0,0 +1,18 @@
+error: `default` is not followed by an item
+ --> $DIR/impl-parsing-2.rs:3:1
+ |
+LL | default unsafe FAIL
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: expected item, found keyword `unsafe`
+ --> $DIR/impl-parsing-2.rs:3:9
+ |
+LL | default unsafe FAIL
+ | ^^^^^^ expected item
+ |
+ = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/impl-parsing.rs b/tests/ui/parser/impl-parsing.rs
index 80ce888..7692a81 100644
--- a/tests/ui/parser/impl-parsing.rs
+++ b/tests/ui/parser/impl-parsing.rs
@@ -2,9 +2,4 @@
impl ! where u8: Copy {} // OK
impl Trait Type {} //~ ERROR missing `for` in a trait impl
-impl Trait .. {} //~ ERROR missing `for` in a trait impl
impl ?Sized for Type {} //~ ERROR expected a trait, found type
-impl ?Sized for .. {} //~ ERROR expected a trait, found type
-
-default unsafe FAIL //~ ERROR expected item, found keyword `unsafe`
-//~^ ERROR `default` is not followed by an item
diff --git a/tests/ui/parser/impl-parsing.stderr b/tests/ui/parser/impl-parsing.stderr
index 6a24a94..b251212 100644
--- a/tests/ui/parser/impl-parsing.stderr
+++ b/tests/ui/parser/impl-parsing.stderr
@@ -9,44 +9,11 @@
LL | impl Trait for Type {}
| +++
-error: missing `for` in a trait impl
- --> $DIR/impl-parsing.rs:5:11
- |
-LL | impl Trait .. {}
- | ^
- |
-help: add `for` here
- |
-LL | impl Trait for .. {}
- | +++
-
error: expected a trait, found type
- --> $DIR/impl-parsing.rs:6:6
+ --> $DIR/impl-parsing.rs:5:6
|
LL | impl ?Sized for Type {}
| ^^^^^^
-error: expected a trait, found type
- --> $DIR/impl-parsing.rs:7:6
- |
-LL | impl ?Sized for .. {}
- | ^^^^^^
-
-error: `default` is not followed by an item
- --> $DIR/impl-parsing.rs:9:1
- |
-LL | default unsafe FAIL
- | ^^^^^^^ the `default` qualifier
- |
- = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
-
-error: expected item, found keyword `unsafe`
- --> $DIR/impl-parsing.rs:9:9
- |
-LL | default unsafe FAIL
- | ^^^^^^ expected item
- |
- = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
diff --git a/tests/ui/parser/keyword-try-as-identifier-edition2018.rs b/tests/ui/parser/keyword-try-as-identifier-edition2018.rs
index 27452f4..795f320 100644
--- a/tests/ui/parser/keyword-try-as-identifier-edition2018.rs
+++ b/tests/ui/parser/keyword-try-as-identifier-edition2018.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
fn main() {
let try = "foo"; //~ error: expected identifier, found reserved keyword `try`
diff --git a/tests/ui/process/win-command-curdir-no-verbatim.rs b/tests/ui/process/win-command-curdir-no-verbatim.rs
new file mode 100644
index 0000000..99943e1
--- /dev/null
+++ b/tests/ui/process/win-command-curdir-no-verbatim.rs
@@ -0,0 +1,36 @@
+// Test that windows verbatim paths in `Command::current_dir` are converted to
+// non-verbatim paths before passing to the subprocess.
+
+//@ run-pass
+//@ only-windows
+//@ needs-subprocess
+
+use std::env;
+use std::process::Command;
+
+fn main() {
+ if env::args().skip(1).any(|s| s == "--child") {
+ child();
+ } else {
+ parent();
+ }
+}
+
+fn parent() {
+ let exe = env::current_exe().unwrap();
+ let dir = env::current_dir().unwrap();
+ let status = Command::new(&exe)
+ .arg("--child")
+ .current_dir(dir.canonicalize().unwrap())
+ .spawn()
+ .unwrap()
+ .wait()
+ .unwrap();
+ assert_eq!(status.code(), Some(0));
+}
+
+fn child() {
+ let current_dir = env::current_dir().unwrap();
+ let current_dir = current_dir.as_os_str().as_encoded_bytes();
+ assert!(!current_dir.starts_with(br"\\?\"));
+}
diff --git a/tests/ui/resolve/dont-compute-arg-names-for-non-fn.rs b/tests/ui/resolve/dont-compute-arg-names-for-non-fn.rs
index 20bbbff..4053ccd 100644
--- a/tests/ui/resolve/dont-compute-arg-names-for-non-fn.rs
+++ b/tests/ui/resolve/dont-compute-arg-names-for-non-fn.rs
@@ -3,7 +3,7 @@
extern crate foreign_trait_with_assoc;
use foreign_trait_with_assoc::Foo;
-// Make sure we don't try to call `fn_arg_names` on a non-fn item.
+// Make sure we don't try to call `fn_arg_idents` on a non-fn item.
impl Foo for Bar {}
//~^ ERROR cannot find type `Bar` in this scope
diff --git a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
index dd604b6..f4f383e 100644
--- a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
+++ b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
@@ -2,7 +2,8 @@
// trait object type to fail, causing an ICE.
//
//@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ edition: 2021
//@ no-prefer-dynamic
//@ only-x86_64-unknown-linux-gnu
//@ build-pass
diff --git a/tests/ui/sanitizer/cfi/coroutine.rs b/tests/ui/sanitizer/cfi/coroutine.rs
index 3ad896a..39a754f 100644
--- a/tests/ui/sanitizer/cfi/coroutine.rs
+++ b/tests/ui/sanitizer/cfi/coroutine.rs
@@ -26,7 +26,7 @@
#[test]
fn general_coroutine() {
- let mut coro = #[coroutine] |x: i32| {
+ let coro = #[coroutine] |x: i32| {
yield x;
"done"
};
diff --git a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
index e5b1e03..7d0c73c 100644
--- a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
+++ b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
@@ -2,7 +2,8 @@
// encode_ty and caused the compiler to ICE.
//
//@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ edition: 2021
//@ no-prefer-dynamic
//@ only-x86_64-unknown-linux-gnu
//@ build-pass
diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs
index 4dc2e4d..e4d47cd 100644
--- a/tests/ui/simd/intrinsic/generic-elements-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs
@@ -1,8 +1,10 @@
//@ run-pass
-#![feature(repr_simd, core_intrinsics)]
+#![feature(repr_simd, intrinsics, core_intrinsics)]
-use std::intrinsics::simd::{simd_extract, simd_insert, simd_shuffle};
+use std::intrinsics::simd::{
+ simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn, simd_shuffle,
+};
#[repr(simd)]
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -70,6 +72,41 @@ fn main() {
all_eq!(simd_extract(x8, 6), 86);
all_eq!(simd_extract(x8, 7), 87);
}
+ unsafe {
+ all_eq!(simd_insert_dyn(x2, 0, 100), i32x2([100, 21]));
+ all_eq!(simd_insert_dyn(x2, 1, 100), i32x2([20, 100]));
+
+ all_eq!(simd_insert_dyn(x4, 0, 100), i32x4([100, 41, 42, 43]));
+ all_eq!(simd_insert_dyn(x4, 1, 100), i32x4([40, 100, 42, 43]));
+ all_eq!(simd_insert_dyn(x4, 2, 100), i32x4([40, 41, 100, 43]));
+ all_eq!(simd_insert_dyn(x4, 3, 100), i32x4([40, 41, 42, 100]));
+
+ all_eq!(simd_insert_dyn(x8, 0, 100), i32x8([100, 81, 82, 83, 84, 85, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 1, 100), i32x8([80, 100, 82, 83, 84, 85, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 2, 100), i32x8([80, 81, 100, 83, 84, 85, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 3, 100), i32x8([80, 81, 82, 100, 84, 85, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 4, 100), i32x8([80, 81, 82, 83, 100, 85, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 5, 100), i32x8([80, 81, 82, 83, 84, 100, 86, 87]));
+ all_eq!(simd_insert_dyn(x8, 6, 100), i32x8([80, 81, 82, 83, 84, 85, 100, 87]));
+ all_eq!(simd_insert_dyn(x8, 7, 100), i32x8([80, 81, 82, 83, 84, 85, 86, 100]));
+
+ all_eq!(simd_extract_dyn(x2, 0), 20);
+ all_eq!(simd_extract_dyn(x2, 1), 21);
+
+ all_eq!(simd_extract_dyn(x4, 0), 40);
+ all_eq!(simd_extract_dyn(x4, 1), 41);
+ all_eq!(simd_extract_dyn(x4, 2), 42);
+ all_eq!(simd_extract_dyn(x4, 3), 43);
+
+ all_eq!(simd_extract_dyn(x8, 0), 80);
+ all_eq!(simd_extract_dyn(x8, 1), 81);
+ all_eq!(simd_extract_dyn(x8, 2), 82);
+ all_eq!(simd_extract_dyn(x8, 3), 83);
+ all_eq!(simd_extract_dyn(x8, 4), 84);
+ all_eq!(simd_extract_dyn(x8, 5), 85);
+ all_eq!(simd_extract_dyn(x8, 6), 86);
+ all_eq!(simd_extract_dyn(x8, 7), 87);
+ }
let y2 = i32x2([120, 121]);
let y4 = i32x4([140, 141, 142, 143]);
diff --git a/tests/ui/suggestions/enum-method-probe.fixed b/tests/ui/suggestions/enum-method-probe.fixed
index 611be99..e097fa8 100644
--- a/tests/ui/suggestions/enum-method-probe.fixed
+++ b/tests/ui/suggestions/enum-method-probe.fixed
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ run-rustfix
#![allow(unused)]
diff --git a/tests/ui/suggestions/enum-method-probe.rs b/tests/ui/suggestions/enum-method-probe.rs
index e183ebd..665ee7d 100644
--- a/tests/ui/suggestions/enum-method-probe.rs
+++ b/tests/ui/suggestions/enum-method-probe.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ run-rustfix
#![allow(unused)]
diff --git a/tests/ui/suggestions/inner_type.fixed b/tests/ui/suggestions/inner_type.fixed
index cfea66b..3dc939d 100644
--- a/tests/ui/suggestions/inner_type.fixed
+++ b/tests/ui/suggestions/inner_type.fixed
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ run-rustfix
pub struct Struct<T> {
diff --git a/tests/ui/suggestions/inner_type.rs b/tests/ui/suggestions/inner_type.rs
index 5fedf3f..81a05c2 100644
--- a/tests/ui/suggestions/inner_type.rs
+++ b/tests/ui/suggestions/inner_type.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ run-rustfix
pub struct Struct<T> {
diff --git a/tests/ui/suggestions/issue-86667.rs b/tests/ui/suggestions/issue-86667.rs
index 1f37e9a..cc5b878 100644
--- a/tests/ui/suggestions/issue-86667.rs
+++ b/tests/ui/suggestions/issue-86667.rs
@@ -1,7 +1,7 @@
// Regression test for #86667, where a garbled suggestion was issued for
// a missing named lifetime parameter.
-//@ compile-flags: --edition 2018
+//@ edition: 2018
async fn a(s1: &str, s2: &str) -> &str {
//~^ ERROR: missing lifetime specifier [E0106]
diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
index be761e4..03e2661 100644
--- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
@@ -6,30 +6,134 @@
|
= help: remove one of these features
-error[E0277]: the trait bound `T: const Trait` is not satisfied
- --> $DIR/unsatisfied-const-trait-bound.rs:29:37
+error[E0391]: cycle detected when evaluating type-level constant
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
- | ^
+ | ^^^^^^^^^^^^^
+ |
+note: ...which requires const-evaluating + checking `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires caching mir of `accept0::{constant#0}` for CTFE...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires elaborating drops for `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires borrow-checking `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires promoting constants in MIR for `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires const checking `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building MIR for `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building an abstract representation for `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building THIR for `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires type-checking `accept0::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:35
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+ = note: ...which again requires evaluating type-level constant, completing the cycle
+note: cycle used when checking that `accept0` is well-formed
+ --> $DIR/unsatisfied-const-trait-bound.rs:29:1
+ |
+LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-error[E0277]: the trait bound `T: const Trait` is not satisfied
- --> $DIR/unsatisfied-const-trait-bound.rs:33:50
+error[E0391]: cycle detected when caching mir of `accept1::{constant#0}` for CTFE
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
- | ^
-
-error[E0277]: the trait bound `Ty: const Trait` is not satisfied
- --> $DIR/unsatisfied-const-trait-bound.rs:22:15
+ | ^^^^^^^^^^^^^
|
-LL | require::<Ty>();
- | ^^
+note: ...which requires elaborating drops for `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
-note: required by a bound in `require`
- --> $DIR/unsatisfied-const-trait-bound.rs:8:15
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires borrow-checking `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
|
-LL | fn require<T: const Trait>() {}
- | ^^^^^^^^^^^ required by this bound in `require`
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires promoting constants in MIR for `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires const checking `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building MIR for `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building an abstract representation for `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires building THIR for `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires type-checking `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires evaluating type-level constant...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `accept1::{constant#0}`...
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+ = note: ...which again requires caching mir of `accept1::{constant#0}` for CTFE, completing the cycle
+note: cycle used when const-evaluating + checking `accept1::{constant#0}`
+ --> $DIR/unsatisfied-const-trait-bound.rs:33:48
+ |
+LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
+ | ^^^^^^^^^^^^^
+ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs b/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs
new file mode 100644
index 0000000..68e234b
--- /dev/null
+++ b/tests/ui/traits/dont-suggest-impl-as-closure-arg.rs
@@ -0,0 +1,5 @@
+// Suggestion to use impl trait in closure parameter is invalid, see issue 138932
+fn main() {
+ let c = |f: dyn Fn()| f();
+ //~^ ERROR: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time
+}
diff --git a/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr b/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr
new file mode 100644
index 0000000..8218990
--- /dev/null
+++ b/tests/ui/traits/dont-suggest-impl-as-closure-arg.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time
+ --> $DIR/dont-suggest-impl-as-closure-arg.rs:3:17
+ |
+LL | let c = |f: dyn Fn()| f();
+ | ^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)`
+ = help: unsized fn params are gated as an unstable feature
+help: function arguments must have a statically known size, borrowed types always have a known size
+ |
+LL | let c = |f: &dyn Fn()| f();
+ | +
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.rs b/tests/ui/traits/issue-85360-eval-obligation-ice.rs
index 931879a..f7c4904 100644
--- a/tests/ui/traits/issue-85360-eval-obligation-ice.rs
+++ b/tests/ui/traits/issue-85360-eval-obligation-ice.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
#![feature(rustc_attrs)]
diff --git a/tests/ui/traits/next-solver/async.fail.stderr b/tests/ui/traits/next-solver/async.fail.stderr
index bc89842..a76a10d 100644
--- a/tests/ui/traits/next-solver/async.fail.stderr
+++ b/tests/ui/traits/next-solver/async.fail.stderr
@@ -1,8 +1,8 @@
-error[E0271]: expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
+error[E0271]: type mismatch resolving `() == i32`
--> $DIR/async.rs:12:17
|
LL | needs_async(async {});
- | ----------- ^^^^^^^^ expected `i32`, found `()`
+ | ----------- ^^^^^^^^ types differ
| |
| required by a bound introduced by this call
|
diff --git a/tests/ui/traits/next-solver/async.rs b/tests/ui/traits/next-solver/async.rs
index fded774..34c0ed0 100644
--- a/tests/ui/traits/next-solver/async.rs
+++ b/tests/ui/traits/next-solver/async.rs
@@ -10,7 +10,7 @@ fn needs_async(_: impl Future<Output = i32>) {}
#[cfg(fail)]
fn main() {
needs_async(async {});
- //[fail]~^ ERROR expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
+ //[fail]~^ ERROR type mismatch resolving `() == i32`
}
#[cfg(pass)]
diff --git a/tests/ui/traits/next-solver/more-object-bound.rs b/tests/ui/traits/next-solver/more-object-bound.rs
index 3d3fdc9..1dad190 100644
--- a/tests/ui/traits/next-solver/more-object-bound.rs
+++ b/tests/ui/traits/next-solver/more-object-bound.rs
@@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
fn transmute<A, B>(x: A) -> B {
foo::<A, B, dyn Trait<A = A, B = B>>(x)
- //~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
+ //~^ ERROR type mismatch resolving `A == B`
}
fn foo<A, B, T: ?Sized>(x: T::A) -> B
diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr
index 39849d4..d04376c 100644
--- a/tests/ui/traits/next-solver/more-object-bound.stderr
+++ b/tests/ui/traits/next-solver/more-object-bound.stderr
@@ -1,17 +1,9 @@
-error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
+error[E0271]: type mismatch resolving `A == B`
--> $DIR/more-object-bound.rs:12:5
|
-LL | fn transmute<A, B>(x: A) -> B {
- | - - expected type parameter
- | |
- | found type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
|
- = note: expected type parameter `B`
- found type parameter `A`
- = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
- = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: required because it appears within the type `dyn Trait<A = A, B = B>`
note: required by a bound in `foo`
--> $DIR/more-object-bound.rs:18:8
diff --git a/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs
index e5208e3..198e619 100644
--- a/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs
+++ b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs
@@ -1,7 +1,8 @@
// Regression test for #132335. This previously ICE'd due to ambiguity
// in MIR typeck.
-//@ compile-flags: -Znext-solver=globally --crate-type lib --edition=2018
+//@ compile-flags: -Znext-solver=globally --crate-type lib
+//@ edition: 2018
//@ check-pass
use core::future::Future;
use core::pin::Pin;
diff --git a/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs
index 8388751..b79926e 100644
--- a/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs
+++ b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs
@@ -3,7 +3,7 @@
// of the async block. This caused borrowck of the recursive
// call to ICE.
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ check-pass
async fn test() {
Box::pin(test()).await;
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
index 94a9484..b2a8c8c 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
@@ -13,7 +13,7 @@ fn needs_bar<S: Bar>() {}
fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() {
needs_bar::<T::Assoc1>();
- //~^ ERROR the trait bound `<T as Foo1>::Assoc1: Bar` is not satisfied
+ //~^ ERROR the trait bound `<T as Foo2>::Assoc2: Bar` is not satisfied
}
fn main() {}
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
index 6f5111a..c4be47e 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `<T as Foo1>::Assoc1: Bar` is not satisfied
+error[E0277]: the trait bound `<T as Foo2>::Assoc2: Bar` is not satisfied
--> $DIR/recursive-self-normalization-2.rs:15:17
|
LL | needs_bar::<T::Assoc1>();
- | ^^^^^^^^^ the trait `Bar` is not implemented for `<T as Foo1>::Assoc1`
+ | ^^^^^^^^^ the trait `Bar` is not implemented for `<T as Foo2>::Assoc2`
|
note: required by a bound in `needs_bar`
--> $DIR/recursive-self-normalization-2.rs:12:17
@@ -11,7 +11,7 @@
| ^^^ required by this bound in `needs_bar`
help: consider further restricting the associated type
|
-LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo1>::Assoc1: Bar {
+LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo2>::Assoc2: Bar {
| ++++++++++++++++++++++++++++++
error: aborting due to 1 previous error
diff --git a/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs b/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs
index f8fa410..50851a5 100644
--- a/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs
+++ b/tests/ui/traits/object/suggestion-trait-object-issue-139174.rs
@@ -1,4 +1,4 @@
-//@compile-flags: --edition 2021
+//@ edition: 2021
fn f<'a>(x: Box<dyn Fn() -> Option<usize + 'a>>) -> usize {
//~^ ERROR expected trait, found builtin type `usize`
diff --git a/tests/ui/traits/trivial-unsized-projection-2.bad.stderr b/tests/ui/traits/trivial-unsized-projection-2.bad.stderr
new file mode 100644
index 0000000..bf8d3c4
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection-2.bad.stderr
@@ -0,0 +1,54 @@
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection-2.rs:22:12
+ |
+LL | const FOO: <Tail as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `Tail`, the trait `Sized` is not implemented for `[()]`
+note: required because it appears within the type `Tail`
+ --> $DIR/trivial-unsized-projection-2.rs:17:8
+ |
+LL | struct Tail([()]);
+ | ^^^^
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection-2.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection-2.rs:22:12
+ |
+LL | const FOO: <Tail as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `Tail`, the trait `Sized` is not implemented for `[()]`
+note: required because it appears within the type `Tail`
+ --> $DIR/trivial-unsized-projection-2.rs:17:8
+ |
+LL | struct Tail([()]);
+ | ^^^^
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection-2.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trivial-unsized-projection-2.bad_new.stderr b/tests/ui/traits/trivial-unsized-projection-2.bad_new.stderr
new file mode 100644
index 0000000..bf8d3c4
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection-2.bad_new.stderr
@@ -0,0 +1,54 @@
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection-2.rs:22:12
+ |
+LL | const FOO: <Tail as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `Tail`, the trait `Sized` is not implemented for `[()]`
+note: required because it appears within the type `Tail`
+ --> $DIR/trivial-unsized-projection-2.rs:17:8
+ |
+LL | struct Tail([()]);
+ | ^^^^
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection-2.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection-2.rs:22:12
+ |
+LL | const FOO: <Tail as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `Tail`, the trait `Sized` is not implemented for `[()]`
+note: required because it appears within the type `Tail`
+ --> $DIR/trivial-unsized-projection-2.rs:17:8
+ |
+LL | struct Tail([()]);
+ | ^^^^
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection-2.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trivial-unsized-projection-2.rs b/tests/ui/traits/trivial-unsized-projection-2.rs
new file mode 100644
index 0000000..af4e12f
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection-2.rs
@@ -0,0 +1,34 @@
+//@ revisions: good bad good_new bad_new
+//@[good_new] compile-flags: -Znext-solver
+//@[bad_new] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[good] check-pass
+//@[good_new] check-pass
+
+#![feature(trivial_bounds)]
+#![allow(trivial_bounds)]
+
+trait Bad {
+ type Assert
+ where
+ Self: Sized;
+}
+
+struct Tail([()]);
+
+impl Bad for Tail {}
+
+#[cfg(any(bad, bad_new))]
+const FOO: <Tail as Bad>::Assert = todo!();
+//[bad]~^ ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad]~| ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad_new]~^^^ ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad_new]~| ERROR the size for values of type `[()]` cannot be known at compilation time
+
+#[cfg(any(good, good_new))]
+// Well-formed in trivially false param-env
+fn foo() where Tail: Sized {
+ let _: <Tail as Bad>::Assert;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trivial-unsized-projection-in-coherence.rs b/tests/ui/traits/trivial-unsized-projection-in-coherence.rs
new file mode 100644
index 0000000..4407d54
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection-in-coherence.rs
@@ -0,0 +1,45 @@
+// Make sure we don't treat missing associated items as rigid
+// during coherence, even if we know they've got an impossible
+// `Sized`-bound. As we check whether the self type is definitely
+// not `Sized` outside of coherence, this check can be incomplete.
+//
+// In this test we only use `impl<T> Overlap<u32> for T` to normalize
+// the field of `MaybeUnsized<T, u32>` when checking whether it's
+// definitely not `Sized`. However, for `MaybeUnsized<u32, u32>` we
+// could also use `impl<U> Overlap<U> for u32` for normalization, which
+// would result in a `Sized` type. cc #139000
+
+struct MaybeUnsized<T: Overlap<U>, U>(<T as Overlap<U>>::MaybeUnsized);
+
+trait ReqSized {
+ type Missing1
+ where
+ Self: Sized;
+ type Missing2
+ where
+ Self: Sized;
+}
+impl<T> ReqSized for MaybeUnsized<T, u32> {}
+
+struct W<T: ?Sized>(T);
+trait Eq<T> {}
+impl<T> Eq<T> for W<T> {}
+
+trait RelateReqSized {}
+impl<T: ReqSized> RelateReqSized for T where W<T::Missing1>: Eq<T::Missing2> {}
+
+trait Overlap<U> {
+ type MaybeUnsized: ?Sized;
+}
+impl<T> Overlap<u32> for T {
+ type MaybeUnsized = str;
+}
+impl<U> Overlap<U> for u32
+//~^ ERROR conflicting implementations of trait `Overlap<u32>` for type `u32`
+where
+ MaybeUnsized<U, u32>: RelateReqSized,
+{
+ type MaybeUnsized = u32;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trivial-unsized-projection-in-coherence.stderr b/tests/ui/traits/trivial-unsized-projection-in-coherence.stderr
new file mode 100644
index 0000000..52fca94
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection-in-coherence.stderr
@@ -0,0 +1,15 @@
+error[E0119]: conflicting implementations of trait `Overlap<u32>` for type `u32`
+ --> $DIR/trivial-unsized-projection-in-coherence.rs:37:1
+ |
+LL | impl<T> Overlap<u32> for T {
+ | -------------------------- first implementation here
+...
+LL | / impl<U> Overlap<U> for u32
+LL | |
+LL | | where
+LL | | MaybeUnsized<U, u32>: RelateReqSized,
+ | |_________________________________________^ conflicting implementation for `u32`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/trivial-unsized-projection.bad.stderr b/tests/ui/traits/trivial-unsized-projection.bad.stderr
new file mode 100644
index 0000000..4aea633
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection.bad.stderr
@@ -0,0 +1,44 @@
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection.rs:20:12
+ |
+LL | const FOO: <[()] as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[()]`
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection.rs:20:12
+ |
+LL | const FOO: <[()] as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[()]`
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trivial-unsized-projection.bad_new.stderr b/tests/ui/traits/trivial-unsized-projection.bad_new.stderr
new file mode 100644
index 0000000..4aea633
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection.bad_new.stderr
@@ -0,0 +1,44 @@
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection.rs:20:12
+ |
+LL | const FOO: <[()] as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[()]`
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error[E0277]: the size for values of type `[()]` cannot be known at compilation time
+ --> $DIR/trivial-unsized-projection.rs:20:12
+ |
+LL | const FOO: <[()] as Bad>::Assert = todo!();
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[()]`
+note: required by a bound in `Bad::Assert`
+ --> $DIR/trivial-unsized-projection.rs:14:15
+ |
+LL | type Assert
+ | ------ required by a bound in this associated type
+LL | where
+LL | Self: Sized;
+ | ^^^^^ required by this bound in `Bad::Assert`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | type Assert: ?Sized
+ | ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trivial-unsized-projection.rs b/tests/ui/traits/trivial-unsized-projection.rs
new file mode 100644
index 0000000..62ff25f
--- /dev/null
+++ b/tests/ui/traits/trivial-unsized-projection.rs
@@ -0,0 +1,32 @@
+//@ revisions: good bad good_new bad_new
+//@[good_new] compile-flags: -Znext-solver
+//@[bad_new] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[good] check-pass
+//@[good_new] check-pass
+
+#![feature(trivial_bounds)]
+#![allow(trivial_bounds)]
+
+trait Bad {
+ type Assert
+ where
+ Self: Sized;
+}
+
+impl Bad for [()] {}
+
+#[cfg(any(bad, bad_new))]
+const FOO: <[()] as Bad>::Assert = todo!();
+//[bad]~^ ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad]~| ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad_new]~^^^ ERROR the size for values of type `[()]` cannot be known at compilation time
+//[bad_new]~| ERROR the size for values of type `[()]` cannot be known at compilation time
+
+#[cfg(any(good, good_new))]
+// Well-formed in trivially false param-env
+fn foo() where [()]: Sized {
+ let _: <[()] as Bad>::Assert;
+}
+
+fn main() {}
diff --git a/tests/ui/try-block/issue-45124.rs b/tests/ui/try-block/issue-45124.rs
index e9e0e76..26e1736 100644
--- a/tests/ui/try-block/issue-45124.rs
+++ b/tests/ui/try-block/issue-45124.rs
@@ -1,6 +1,6 @@
//@ run-pass
#![allow(unreachable_code)]
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-bad-lifetime.rs b/tests/ui/try-block/try-block-bad-lifetime.rs
index bfff757..9b45b0d 100644
--- a/tests/ui/try-block/try-block-bad-lifetime.rs
+++ b/tests/ui/try-block/try-block-bad-lifetime.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-bad-type.rs b/tests/ui/try-block/try-block-bad-type.rs
index 71eb832..00cd0af 100644
--- a/tests/ui/try-block/try-block-bad-type.rs
+++ b/tests/ui/try-block/try-block-bad-type.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-catch.rs b/tests/ui/try-block/try-block-catch.rs
index c3aa442..170d5ba 100644
--- a/tests/ui/try-block/try-block-catch.rs
+++ b/tests/ui/try-block/try-block-catch.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-in-edition2015.rs b/tests/ui/try-block/try-block-in-edition2015.rs
index 423269d..4ebe2d3 100644
--- a/tests/ui/try-block/try-block-in-edition2015.rs
+++ b/tests/ui/try-block/try-block-in-edition2015.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2015
+//@ edition: 2015
pub fn main() {
let try_result: Option<_> = try {
diff --git a/tests/ui/try-block/try-block-in-match-arm.rs b/tests/ui/try-block/try-block-in-match-arm.rs
index cecbf72..703b1c5 100644
--- a/tests/ui/try-block/try-block-in-match-arm.rs
+++ b/tests/ui/try-block/try-block-in-match-arm.rs
@@ -1,5 +1,5 @@
//@ check-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-in-match.rs b/tests/ui/try-block/try-block-in-match.rs
index 5c62f41..63a3200 100644
--- a/tests/ui/try-block/try-block-in-match.rs
+++ b/tests/ui/try-block/try-block-in-match.rs
@@ -1,5 +1,5 @@
//@ run-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-in-return.rs b/tests/ui/try-block/try-block-in-return.rs
index ee5ca69..7dc023b 100644
--- a/tests/ui/try-block/try-block-in-return.rs
+++ b/tests/ui/try-block/try-block-in-return.rs
@@ -1,5 +1,5 @@
//@ run-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-in-while.rs b/tests/ui/try-block/try-block-in-while.rs
index 88a9713..d623254 100644
--- a/tests/ui/try-block/try-block-in-while.rs
+++ b/tests/ui/try-block/try-block-in-while.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-maybe-bad-lifetime.rs b/tests/ui/try-block/try-block-maybe-bad-lifetime.rs
index 52ec0c4..14adee8 100644
--- a/tests/ui/try-block/try-block-maybe-bad-lifetime.rs
+++ b/tests/ui/try-block/try-block-maybe-bad-lifetime.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-opt-init.rs b/tests/ui/try-block/try-block-opt-init.rs
index fbe7f90..55ac5b4 100644
--- a/tests/ui/try-block/try-block-opt-init.rs
+++ b/tests/ui/try-block/try-block-opt-init.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-type-error.rs b/tests/ui/try-block/try-block-type-error.rs
index 79cdb7a..4e482b4 100644
--- a/tests/ui/try-block/try-block-type-error.rs
+++ b/tests/ui/try-block/try-block-type-error.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-unreachable-code-lint.rs b/tests/ui/try-block/try-block-unreachable-code-lint.rs
index 62c74b7..9135882 100644
--- a/tests/ui/try-block/try-block-unreachable-code-lint.rs
+++ b/tests/ui/try-block/try-block-unreachable-code-lint.rs
@@ -1,6 +1,6 @@
// Test unreachable_code lint for `try {}` block ok-wrapping. See issues #54165, #63324.
-//@ compile-flags: --edition 2018
+//@ edition: 2018
//@ check-pass
#![feature(try_blocks)]
#![warn(unreachable_code)]
diff --git a/tests/ui/try-block/try-block-unused-delims.fixed b/tests/ui/try-block/try-block-unused-delims.fixed
index 348eb8f..4769c45 100644
--- a/tests/ui/try-block/try-block-unused-delims.fixed
+++ b/tests/ui/try-block/try-block-unused-delims.fixed
@@ -1,5 +1,5 @@
//@ check-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
//@ run-rustfix
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block-unused-delims.rs b/tests/ui/try-block/try-block-unused-delims.rs
index f119e10..0520d1d 100644
--- a/tests/ui/try-block/try-block-unused-delims.rs
+++ b/tests/ui/try-block/try-block-unused-delims.rs
@@ -1,5 +1,5 @@
//@ check-pass
-//@ compile-flags: --edition 2018
+//@ edition: 2018
//@ run-rustfix
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-block.rs b/tests/ui/try-block/try-block.rs
index 7520cba..3fa0d2b 100644
--- a/tests/ui/try-block/try-block.rs
+++ b/tests/ui/try-block/try-block.rs
@@ -2,7 +2,7 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
-//@ compile-flags: --edition 2018
+//@ edition: 2018
#![feature(try_blocks)]
diff --git a/tests/ui/try-block/try-is-identifier-edition2015.rs b/tests/ui/try-block/try-is-identifier-edition2015.rs
index 54bd049..99f4d20 100644
--- a/tests/ui/try-block/try-is-identifier-edition2015.rs
+++ b/tests/ui/try-block/try-is-identifier-edition2015.rs
@@ -1,7 +1,7 @@
//@ run-pass
#![allow(non_camel_case_types)]
-//@ compile-flags: --edition 2015
+//@ edition: 2015
fn main() {
let try = 2;
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
index 4f3f6d3..f69fd57 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2021
+//@ edition: 2021
//@ build-pass
#![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
index cad1cbf..736a9df 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
@@ -1,4 +1,5 @@
-//@ compile-flags: --edition=2021 --crate-type=lib
+//@ compile-flags: --crate-type=lib
+//@ edition: 2021
//@ rustc-env:RUST_BACKTRACE=0
//@ check-pass
diff --git a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
index 13f5d8b..c58d919 100644
--- a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
+++ b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
@@ -1,4 +1,4 @@
-error[E0049]: type `Baz` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated type `Baz` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/impl-trait-in-type-alias-with-bad-substs.rs:19:14
|
LL | type Baz<'a>;
diff --git a/tests/ui/type-alias-impl-trait/issue-93411.rs b/tests/ui/type-alias-impl-trait/issue-93411.rs
index 11cbb87..614d2d0 100644
--- a/tests/ui/type-alias-impl-trait/issue-93411.rs
+++ b/tests/ui/type-alias-impl-trait/issue-93411.rs
@@ -2,7 +2,7 @@
// this test used to stack overflow due to infinite recursion.
//@ check-pass
-//@ compile-flags: --edition=2018
+//@ edition: 2018
use std::future::Future;
diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
index 08f3c40..7f0f6a2 100644
--- a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
+++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
@@ -1,7 +1,7 @@
#![feature(type_alias_impl_trait)]
//@ check-pass
//@ revisions: default edition2021
-//@[edition2021] compile-flags: --edition 2021
+//@[edition2021]edition: 2021
fn main() {
type T = impl Copy;
diff --git a/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-a.rs b/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-a.rs
new file mode 100644
index 0000000..87d8366
--- /dev/null
+++ b/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-a.rs
@@ -0,0 +1,5 @@
+//@ edition: 2021
+
+pub trait Foo {
+ fn foo();
+}
diff --git a/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-b.rs b/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-b.rs
new file mode 100644
index 0000000..9e90e0f
--- /dev/null
+++ b/tests/ui/typeck/auxiliary/suggest-trait-reexported-as-not-doc-visible-b.rs
@@ -0,0 +1,14 @@
+// ignore-tidy-linelength
+//@ edition: 2021
+//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_a=suggest-trait-reexported-as-not-doc-visible-a.rs
+
+pub struct Bar;
+
+impl __DocHidden::Foo for Bar {
+ fn foo() {}
+}
+
+#[doc(hidden)]
+pub mod __DocHidden {
+ pub use suggest_trait_reexported_as_not_doc_visible_a::Foo;
+}
diff --git a/tests/ui/typeck/issue-65611.rs b/tests/ui/typeck/issue-65611.rs
index 7645311..0dae759 100644
--- a/tests/ui/typeck/issue-65611.rs
+++ b/tests/ui/typeck/issue-65611.rs
@@ -58,6 +58,5 @@ fn main() {
let mut buffer = ArrayVec::new();
let x = buffer.last().unwrap().0.clone();
//~^ ERROR type annotations needed
- //~| ERROR no field `0` on type `&_`
buffer.reverse();
}
diff --git a/tests/ui/typeck/issue-65611.stderr b/tests/ui/typeck/issue-65611.stderr
index 2278450..52f0f0c 100644
--- a/tests/ui/typeck/issue-65611.stderr
+++ b/tests/ui/typeck/issue-65611.stderr
@@ -4,13 +4,6 @@
LL | let x = buffer.last().unwrap().0.clone();
| ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
-error[E0609]: no field `0` on type `&_`
- --> $DIR/issue-65611.rs:59:36
- |
-LL | let x = buffer.last().unwrap().0.clone();
- | ^ unknown field
+error: aborting due to 1 previous error
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0282, E0609.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs
new file mode 100644
index 0000000..3cb775e
--- /dev/null
+++ b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.rs
@@ -0,0 +1,11 @@
+// ignore-tidy-linelength
+//@ edition: 2021
+//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_a=suggest-trait-reexported-as-not-doc-visible-a.rs
+//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_b=suggest-trait-reexported-as-not-doc-visible-b.rs
+
+use suggest_trait_reexported_as_not_doc_visible_b::Bar;
+
+fn main() {
+ Bar::foo();
+ //~^ ERROR: no function or associated item named `foo` found for struct `Bar` in the current scope [E0599]
+}
diff --git a/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr
new file mode 100644
index 0000000..9128ee684
--- /dev/null
+++ b/tests/ui/typeck/suggest-trait-reexported-as-not-doc-visible.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no function or associated item named `foo` found for struct `Bar` in the current scope
+ --> $DIR/suggest-trait-reexported-as-not-doc-visible.rs:9:10
+ |
+LL | Bar::foo();
+ | ^^^ function or associated item not found in `Bar`
+ |
+ = help: items from traits can only be used if the trait is in scope
+help: trait `Foo` which provides `foo` is implemented but not in scope; perhaps you want to import it
+ |
+LL + use suggest_trait_reexported_as_not_doc_visible_a::Foo;
+ |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/use/auxiliary/extern-use-primitive-type-lib.rs b/tests/ui/use/auxiliary/extern-use-primitive-type-lib.rs
index 18aa329..c21eea7 100644
--- a/tests/ui/use/auxiliary/extern-use-primitive-type-lib.rs
+++ b/tests/ui/use/auxiliary/extern-use-primitive-type-lib.rs
@@ -1,3 +1,3 @@
-//@ compile-flags: --edition=2018
+//@ edition: 2018
pub use u32;
diff --git a/triagebot.toml b/triagebot.toml
index 756536d..4b6af3a 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1123,8 +1123,8 @@
warn_non_default_branch.enable = true
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
users_on_vacation = [
+ "fmease",
"jyn514",
- "saethlin",
"Noratrieb",
]
@@ -1338,9 +1338,11 @@
"/src/doc/nomicon" = ["@ehuss"]
"/src/doc/reference" = ["@ehuss"]
"/src/doc/rust-by-example" = ["@ehuss"]
+"/src/doc/rustc" = ["compiler", "@ehuss"]
"/src/doc/rustc-dev-guide" = ["compiler"]
"/src/doc/rustdoc" = ["rustdoc"]
"/src/doc/style-guide" = ["style-team"]
+"/src/doc/unstable-book" = ["compiler"]
"/src/etc" = ["@Mark-Simulacrum"]
"/src/librustdoc" = ["rustdoc"]
"/src/llvm-project" = ["@cuviper"]