From 8e599b0daac87f8ec4a86f5e62ebf01d5f4e21f5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 13 Dec 2024 18:29:41 +0100 Subject: [PATCH 001/262] de-stabilize bench attribute --- library/core/src/macros/mod.rs | 1 - tests/ui/feature-gates/bench.rs | 2 -- tests/ui/feature-gates/bench.stderr | 40 ++++++++--------------------- tests/ui/lint/expansion-time.rs | 7 ----- tests/ui/lint/expansion-time.stderr | 33 ++---------------------- 5 files changed, 12 insertions(+), 71 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ab674b58902b..f10a58618cd8 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1683,7 +1683,6 @@ pub(crate) mod builtin { #[unstable( feature = "test", issue = "50297", - soft, reason = "`bench` is a part of custom test frameworks which are unstable" )] #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)] diff --git a/tests/ui/feature-gates/bench.rs b/tests/ui/feature-gates/bench.rs index 12e646f7a323..94c8992a8fe6 100644 --- a/tests/ui/feature-gates/bench.rs +++ b/tests/ui/feature-gates/bench.rs @@ -1,9 +1,7 @@ //@ edition:2018 #[bench] //~ ERROR use of unstable library feature `test` - //~| WARN this was previously accepted fn bench() {} use bench as _; //~ ERROR use of unstable library feature `test` - //~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/feature-gates/bench.stderr b/tests/ui/feature-gates/bench.stderr index de78e863012d..f5fc579b23be 100644 --- a/tests/ui/feature-gates/bench.stderr +++ b/tests/ui/feature-gates/bench.stderr @@ -1,43 +1,23 @@ -error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable +error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable --> $DIR/bench.rs:3:3 | LL | #[bench] | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 - = note: `#[deny(soft_unstable)]` on by default + = note: see issue #50297 for more information + = help: add `#![feature(test)]` 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: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable - --> $DIR/bench.rs:7:5 +error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable + --> $DIR/bench.rs:6:5 | LL | use bench as _; | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 + = note: see issue #50297 for more information + = help: add `#![feature(test)]` 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 2 previous errors -Future incompatibility report: Future breakage diagnostic: -error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable - --> $DIR/bench.rs:3:3 - | -LL | #[bench] - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 - = note: `#[deny(soft_unstable)]` on by default - -Future breakage diagnostic: -error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable - --> $DIR/bench.rs:7:5 - | -LL | use bench as _; - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 - = note: `#[deny(soft_unstable)]` on by default - +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/expansion-time.rs b/tests/ui/lint/expansion-time.rs index d0f26a87385c..c13649c93a1b 100644 --- a/tests/ui/lint/expansion-time.rs +++ b/tests/ui/lint/expansion-time.rs @@ -9,13 +9,6 @@ macro_rules! foo { macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier //~| WARN this was previously accepted -#[warn(soft_unstable)] -mod benches { - #[bench] //~ WARN use of unstable library feature `test` - //~| WARN this was previously accepted - fn foo() {} -} - #[deprecated = "reason"] macro_rules! deprecated { () => {} diff --git a/tests/ui/lint/expansion-time.stderr b/tests/ui/lint/expansion-time.stderr index f65627c2c087..f24d1b68a8da 100644 --- a/tests/ui/lint/expansion-time.stderr +++ b/tests/ui/lint/expansion-time.stderr @@ -26,20 +26,6 @@ note: the lint level is defined here LL | #[warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable - --> $DIR/expansion-time.rs:14:7 - | -LL | #[bench] - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 -note: the lint level is defined here - --> $DIR/expansion-time.rs:12:8 - | -LL | #[warn(soft_unstable)] - | ^^^^^^^^^^^^^ - warning: include macro expected single expression in source --> $DIR/expansion-time-include.rs:4:1 | @@ -47,12 +33,12 @@ LL | 2 | ^ | note: the lint level is defined here - --> $DIR/expansion-time.rs:29:8 + --> $DIR/expansion-time.rs:22:8 | LL | #[warn(incomplete_include)] | ^^^^^^^^^^^^^^^^^^ -warning: 4 warnings emitted +warning: 3 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: missing fragment specifier @@ -69,18 +55,3 @@ note: the lint level is defined here LL | #[warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Future breakage diagnostic: -warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable - --> $DIR/expansion-time.rs:14:7 - | -LL | #[bench] - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 -note: the lint level is defined here - --> $DIR/expansion-time.rs:12:8 - | -LL | #[warn(soft_unstable)] - | ^^^^^^^^^^^^^ - From f5c63b9e63b841a3b60731769078571514a1cdad Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 13 Dec 2024 20:14:13 +0100 Subject: [PATCH 002/262] the soft_unstable lint cannot have an example that will keep working --- compiler/rustc_lint_defs/src/builtin.rs | 32 +++---------------------- src/tools/lint-docs/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 54e927df3c42..a6d437b71a4e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2389,37 +2389,11 @@ declare_lint! { } declare_lint! { - /// The `soft_unstable` lint detects unstable features that were - /// unintentionally allowed on stable. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #[cfg(test)] - /// extern crate test; - /// - /// #[bench] - /// fn name(b: &mut test::Bencher) { - /// b.iter(|| 123) - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The [`bench` attribute] was accidentally allowed to be specified on - /// the [stable release channel]. Turning this to a hard error would have - /// broken some projects. This lint allows those projects to continue to - /// build correctly when [`--cap-lints`] is used, but otherwise signal an - /// error that `#[bench]` should not be used on the stable channel. This - /// is a [future-incompatible] lint to transition this to a hard error in - /// the future. See [issue #64266] for more details. + /// The `soft_unstable` lint detects unstable features that were unintentionally allowed on + /// stable. This is a [future-incompatible] lint to transition this to a hard error in the + /// future. See [issue #64266] for more details. /// /// [issue #64266]: https://github.com/rust-lang/rust/issues/64266 - /// [`bench` attribute]: https://doc.rust-lang.org/nightly/unstable-book/library-features/test.html - /// [stable release channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html - /// [`--cap-lints`]: https://doc.rust-lang.org/rustc/lints/levels.html#capping-lints /// [future-incompatible]: ../index.md#future-incompatible-lints pub SOFT_UNSTABLE, Deny, diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 8c7ff08ccd72..b54a4dba41c7 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -306,6 +306,7 @@ impl<'a> LintExtractor<'a> { if matches!( lint.name.as_str(), "unused_features" // broken lint + | "soft_unstable" // cannot have a stable example ) { return Ok(()); } From a3c5b6a2dcd7ad57dda3d483aa29f71208f56dd6 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 28 Feb 2025 00:28:41 +0100 Subject: [PATCH 003/262] Fix span info for mir::Operand Fixes #19172 --- .../rust-analyzer/crates/hir-ty/src/mir.rs | 23 ++++-- .../crates/hir-ty/src/mir/borrowck.rs | 22 +++--- .../crates/hir-ty/src/mir/eval.rs | 18 ++--- .../crates/hir-ty/src/mir/lower.rs | 72 ++++++++++++------- .../crates/hir-ty/src/mir/lower/as_place.rs | 8 +-- .../hir-ty/src/mir/lower/pattern_matching.rs | 47 ++++++++---- .../crates/hir-ty/src/mir/monomorphization.rs | 8 +-- .../crates/hir-ty/src/mir/pretty.rs | 12 ++-- .../src/handlers/moved_out_of_ref.rs | 19 ++++- 9 files changed, 147 insertions(+), 82 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 247f0ec429fc..43408eb75e27 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -77,7 +77,14 @@ pub struct Local { /// currently implements it, but it seems like this may be something to check against in the /// validator. #[derive(Debug, PartialEq, Eq, Clone)] -pub enum Operand { +pub struct Operand { + kind: OperandKind, + // FIXME : This should actually just be of type `MirSpan`. + span: Option, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum OperandKind { /// Creates a value by loading the given place. /// /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there @@ -101,7 +108,13 @@ pub enum Operand { impl Operand { fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap, ty: Ty) -> Self { - Operand::Constant(intern_const_scalar(ConstScalar::Bytes(data, memory_map), ty)) + Operand { + kind: OperandKind::Constant(intern_const_scalar( + ConstScalar::Bytes(data, memory_map), + ty, + )), + span: None, + } } fn from_bytes(data: Box<[u8]>, ty: Ty) -> Self { @@ -1076,11 +1089,11 @@ impl MirBody { f: &mut impl FnMut(&mut Place, &mut ProjectionStore), store: &mut ProjectionStore, ) { - match op { - Operand::Copy(p) | Operand::Move(p) => { + match &mut op.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => { f(p, store); } - Operand::Constant(_) | Operand::Static(_) => (), + OperandKind::Constant(_) | OperandKind::Static(_) => (), } } for (_, block) in self.basic_blocks.iter_mut() { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index d9938fc60cd7..769510c42537 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -15,13 +15,13 @@ use crate::{ ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags, db::{HirDatabase, InternedClosure}, display::DisplayTarget, - mir::Operand, + mir::OperandKind, utils::ClosureSubst, }; use super::{ - BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Place, - ProjectionElem, Rvalue, StatementKind, TerminatorKind, + BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Operand, + Place, ProjectionElem, Rvalue, StatementKind, TerminatorKind, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -120,8 +120,8 @@ fn make_fetch_closure_field( fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec { let mut result = vec![]; - let mut for_operand = |op: &Operand, span: MirSpan| match op { - Operand::Copy(p) | Operand::Move(p) => { + let mut for_operand = |op: &Operand, span: MirSpan| match op.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => { let mut ty: Ty = body.locals[p.local].ty.clone(); let mut is_dereference_of_ref = false; for proj in p.projection.lookup(&body.projection_store) { @@ -139,10 +139,10 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec && !ty.clone().is_copy(db, body.owner) && !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR) { - result.push(MovedOutOfRef { span, ty }); + result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty }); } } - Operand::Constant(_) | Operand::Static(_) => (), + OperandKind::Constant(_) | OperandKind::Static(_) => (), }; for (_, block) in body.basic_blocks.iter() { db.unwind_if_revision_cancelled(); @@ -215,8 +215,8 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec { let mut result = vec![]; - let mut for_operand = |op: &Operand, span: MirSpan| match op { - Operand::Copy(p) | Operand::Move(p) => { + let mut for_operand = |op: &Operand, span: MirSpan| match op.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => { let mut ty: Ty = body.locals[p.local].ty.clone(); for proj in p.projection.lookup(&body.projection_store) { ty = proj.projected_ty( @@ -232,7 +232,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec result.push(PartiallyMoved { span, ty, local: p.local }); } } - Operand::Constant(_) | Operand::Static(_) => (), + OperandKind::Constant(_) | OperandKind::Static(_) => (), }; for (_, block) in body.basic_blocks.iter() { db.unwind_if_revision_cancelled(); @@ -500,7 +500,7 @@ fn record_usage(local: LocalId, result: &mut ArenaMap } fn record_usage_for_operand(arg: &Operand, result: &mut ArenaMap) { - if let Operand::Copy(p) | Operand::Move(p) = arg { + if let OperandKind::Copy(p) | OperandKind::Move(p) = arg.kind { record_usage(p.local, result); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index ee412dd00b3a..00e51ae20571 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -46,7 +46,7 @@ use crate::{ use super::{ AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan, - Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind, + Operand, OperandKind, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind, TerminatorKind, UnOp, return_slot, }; @@ -867,10 +867,10 @@ impl Evaluator<'_> { } fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result { - Ok(match o { - Operand::Copy(p) | Operand::Move(p) => self.place_ty(p, locals)?, - Operand::Constant(c) => c.data(Interner).ty.clone(), - &Operand::Static(s) => { + Ok(match &o.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?, + OperandKind::Constant(c) => c.data(Interner).ty.clone(), + &OperandKind::Static(s) => { let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone(); TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner) } @@ -1884,16 +1884,16 @@ impl Evaluator<'_> { } fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result { - Ok(match it { - Operand::Copy(p) | Operand::Move(p) => { + Ok(match &it.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => { locals.drop_flags.remove_place(p, &locals.body.projection_store); self.eval_place(p, locals)? } - Operand::Static(st) => { + OperandKind::Static(st) => { let addr = self.eval_static(*st, locals)?; Interval::new(addr, self.ptr_size()) } - Operand::Constant(konst) => self.allocate_const_in_heap(locals, konst)?, + OperandKind::Constant(konst) => self.allocate_const_in_heap(locals, konst)?, }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 95c93b5f3edd..9816902fc07b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -50,6 +50,8 @@ use crate::{ utils::ClosureSubst, }; +use super::OperandKind; + mod as_place; mod pattern_matching; @@ -329,7 +331,7 @@ impl<'ctx> MirLowerCtx<'ctx> { let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else { return Ok(None); }; - Ok(Some((Operand::Copy(p), current))) + Ok(Some((Operand { kind: OperandKind::Copy(p), span: Some(expr_id.into()) }, current))) } fn lower_expr_to_place_with_adjust( @@ -352,7 +354,12 @@ impl<'ctx> MirLowerCtx<'ctx> { else { return Ok(None); }; - self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into()); + self.push_assignment( + current, + place, + Operand { kind: OperandKind::Copy(p), span: None }.into(), + expr_id.into(), + ); Ok(Some(current)) } Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => { @@ -376,7 +383,7 @@ impl<'ctx> MirLowerCtx<'ctx> { place, Rvalue::Cast( CastKind::PointerCoercion(*cast), - Operand::Copy(p), + Operand { kind: OperandKind::Copy(p), span: None }, last.target.clone(), ), expr_id.into(), @@ -482,7 +489,7 @@ impl<'ctx> MirLowerCtx<'ctx> { self.push_assignment( current, place, - Operand::Copy(temp).into(), + Operand { kind: OperandKind::Copy(temp), span: None }.into(), expr_id.into(), ); Ok(Some(current)) @@ -523,21 +530,24 @@ impl<'ctx> MirLowerCtx<'ctx> { self.push_assignment( current, place, - Operand::Constant( - ConstData { - ty, - value: chalk_ir::ConstValue::BoundVar(BoundVar::new( - DebruijnIndex::INNERMOST, - generics.type_or_const_param_idx(p.into()).ok_or( - MirLowerError::TypeError( - "fail to lower const generic param", - ), - )?, - )), - } - .intern(Interner), - ) - .into(), + Rvalue::from(Operand { + kind: OperandKind::Constant( + ConstData { + ty, + value: chalk_ir::ConstValue::BoundVar(BoundVar::new( + DebruijnIndex::INNERMOST, + generics.type_or_const_param_idx(p.into()).ok_or( + MirLowerError::TypeError( + "fail to lower const generic param", + ), + )?, + )), + } + .intern(Interner), + ) + .into(), + span: None, + }), expr_id.into(), ); Ok(Some(current)) @@ -882,7 +892,7 @@ impl<'ctx> MirLowerCtx<'ctx> { })), &mut self.result.projection_store, ); - Operand::Copy(p) + Operand { kind: OperandKind::Copy(p), span: None } } }) .collect(), @@ -984,7 +994,12 @@ impl<'ctx> MirLowerCtx<'ctx> { else { return Ok(None); }; - self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into()); + self.push_assignment( + current, + place, + Operand { kind: OperandKind::Copy(p), span: None }.into(), + expr_id.into(), + ); Ok(Some(current)) } Expr::UnaryOp { @@ -1061,8 +1076,11 @@ impl<'ctx> MirLowerCtx<'ctx> { else { return Ok(None); }; - let r_value = - Rvalue::CheckedBinaryOp(op.into(), Operand::Copy(lhs_place), rhs_op); + let r_value = Rvalue::CheckedBinaryOp( + op.into(), + Operand { kind: OperandKind::Copy(lhs_place), span: None }, + rhs_op, + ); self.push_assignment(current, lhs_place, r_value, expr_id.into()); return Ok(Some(current)); } @@ -1237,9 +1255,11 @@ impl<'ctx> MirLowerCtx<'ctx> { Rvalue::Ref(*bk, p), capture_spans[0], ); - operands.push(Operand::Move(tmp)); + operands.push(Operand { kind: OperandKind::Move(tmp), span: None }); + } + CaptureKind::ByValue => { + operands.push(Operand { kind: OperandKind::Move(p), span: None }) } - CaptureKind::ByValue => operands.push(Operand::Move(p)), } } self.push_assignment( @@ -1481,7 +1501,7 @@ impl<'ctx> MirLowerCtx<'ctx> { .const_eval(const_id, subst, None) .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))? }; - Ok(Operand::Constant(c)) + Ok(Operand { kind: OperandKind::Constant(c), span: None }) } fn write_bytes_to_place( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index 7b0ee22d51fc..c2077d669fb2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -1,6 +1,6 @@ //! MIR lowering for places -use crate::mir::MutBorrowKind; +use crate::mir::{MutBorrowKind, Operand, OperandKind}; use super::*; use hir_def::FunctionId; @@ -156,7 +156,7 @@ impl MirLowerCtx<'_> { self.push_assignment( current, temp, - Operand::Static(s).into(), + Operand { kind: OperandKind::Static(s), span: None }.into(), expr_id.into(), ); Ok(Some(( @@ -306,7 +306,7 @@ impl MirLowerCtx<'_> { ); let Some(current) = self.lower_call( index_fn_op, - Box::new([Operand::Copy(place), index_operand]), + Box::new([Operand { kind: OperandKind::Copy(place), span: None }, index_operand]), result, current, false, @@ -366,7 +366,7 @@ impl MirLowerCtx<'_> { let mut result: Place = self.temp(target_ty_ref, current, span)?.into(); let Some(current) = self.lower_call( deref_fn_op, - Box::new([Operand::Copy(ref_place)]), + Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]), result, current, false, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index d6b2100253f6..7607560bdd1a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -5,10 +5,10 @@ use hir_def::{AssocItemId, hir::ExprId}; use crate::{ BindingMode, mir::{ - LocalId, MutBorrowKind, + LocalId, MutBorrowKind, Operand, OperandKind, lower::{ BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner, - MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place, + MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Pat, PatId, Place, PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue, Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind, ValueNs, VariantData, VariantId, @@ -217,10 +217,14 @@ impl MirLowerCtx<'_> { self.push_assignment( current, discr, - Rvalue::CheckedBinaryOp(binop, lv, Operand::Copy(cond_place)), + Rvalue::CheckedBinaryOp( + binop, + lv, + Operand { kind: OperandKind::Copy(cond_place), span: None }, + ), pattern.into(), ); - let discr = Operand::Copy(discr); + let discr = Operand { kind: OperandKind::Copy(discr), span: None }; self.set_terminator( current, TerminatorKind::SwitchInt { @@ -262,7 +266,10 @@ impl MirLowerCtx<'_> { self.set_terminator( current, TerminatorKind::SwitchInt { - discr: Operand::Copy(place_len), + discr: Operand { + kind: OperandKind::Copy(place_len), + span: None, + }, targets: SwitchTargets::static_if( pattern_len as u128, next, @@ -282,10 +289,14 @@ impl MirLowerCtx<'_> { self.push_assignment( current, discr, - Rvalue::CheckedBinaryOp(BinOp::Le, c, Operand::Copy(place_len)), + Rvalue::CheckedBinaryOp( + BinOp::Le, + c, + Operand { kind: OperandKind::Copy(place_len), span: None }, + ), pattern.into(), ); - let discr = Operand::Copy(discr); + let discr = Operand { kind: OperandKind::Copy(discr), span: None }; self.set_terminator( current, TerminatorKind::SwitchInt { @@ -412,8 +423,8 @@ impl MirLowerCtx<'_> { tmp2, Rvalue::CheckedBinaryOp( BinOp::Eq, - Operand::Copy(tmp), - Operand::Copy(cond_place), + Operand { kind: OperandKind::Copy(tmp), span: None }, + Operand { kind: OperandKind::Copy(cond_place), span: None }, ), span, ); @@ -422,7 +433,7 @@ impl MirLowerCtx<'_> { self.set_terminator( current, TerminatorKind::SwitchInt { - discr: Operand::Copy(tmp2), + discr: Operand { kind: OperandKind::Copy(tmp2), span: None }, targets: SwitchTargets::static_if(1, next, else_target), }, span, @@ -491,7 +502,7 @@ impl MirLowerCtx<'_> { self.push_assignment( current, lhs_place, - Operand::Copy(cond_place).into(), + Operand { kind: OperandKind::Copy(cond_place), span: None }.into(), expr.into(), ); (current, current_else) @@ -528,7 +539,9 @@ impl MirLowerCtx<'_> { current, target_place.into(), match mode { - BindingMode::Move => Operand::Copy(cond_place).into(), + BindingMode::Move => { + Operand { kind: OperandKind::Copy(cond_place), span: None }.into() + } BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place), BindingMode::Ref(Mutability::Mut) => { Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place) @@ -552,10 +565,14 @@ impl MirLowerCtx<'_> { self.push_assignment( current, discr, - Rvalue::CheckedBinaryOp(BinOp::Eq, c, Operand::Copy(cond_place)), + Rvalue::CheckedBinaryOp( + BinOp::Eq, + c, + Operand { kind: OperandKind::Copy(cond_place), span: None }, + ), pattern.into(), ); - let discr = Operand::Copy(discr); + let discr = Operand { kind: OperandKind::Copy(discr), span: None }; self.set_terminator( current, TerminatorKind::SwitchInt { @@ -588,7 +605,7 @@ impl MirLowerCtx<'_> { self.set_terminator( current, TerminatorKind::SwitchInt { - discr: Operand::Copy(tmp), + discr: Operand { kind: OperandKind::Copy(tmp), span: None }, targets: SwitchTargets::static_if(e, next, *else_target), }, span, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index c733c7ed845a..99be0d57c9a8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -25,7 +25,7 @@ use crate::{ infer::normalize, }; -use super::{MirBody, MirLowerError, Operand, Rvalue, StatementKind, TerminatorKind}; +use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, TerminatorKind}; macro_rules! not_supported { ($it: expr) => { @@ -170,8 +170,8 @@ impl Filler<'_> { } fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> { - match op { - Operand::Constant(c) => { + match &mut op.kind { + OperandKind::Constant(c) => { match &c.data(Interner).value { chalk_ir::ConstValue::BoundVar(b) => { let resolved = self @@ -215,7 +215,7 @@ impl Filler<'_> { } self.fill_const(c)?; } - Operand::Copy(_) | Operand::Move(_) | Operand::Static(_) => (), + OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (), } Ok(()) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index d9c0000fffd0..b65cf9dab502 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs @@ -18,8 +18,8 @@ use crate::{ }; use super::{ - AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, Place, - Rvalue, UnOp, + AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, OperandKind, + Place, Rvalue, UnOp, }; macro_rules! w { @@ -383,14 +383,14 @@ impl<'a> MirPrettyCtx<'a> { } fn operand(&mut self, r: &Operand) { - match r { - Operand::Copy(p) | Operand::Move(p) => { + match &r.kind { + OperandKind::Copy(p) | OperandKind::Move(p) => { // MIR at the time of writing doesn't have difference between move and copy, so we show them // equally. Feel free to change it. self.place(p); } - Operand::Constant(c) => w!(self, "Const({})", self.hir_display(c)), - Operand::Static(s) => w!(self, "Static({:?})", s), + OperandKind::Constant(c) => w!(self, "Const({})", self.hir_display(c)), + OperandKind::Static(s) => w!(self, "Static({:?})", s), } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs index 7d0f10983d73..da8eed29b03d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs @@ -18,7 +18,22 @@ pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOf mod tests { use crate::tests::check_diagnostics; - // FIXME: spans are broken + #[test] + fn abc() { + check_diagnostics( + r#" +struct NotCopy; +struct S { + field: NotCopy, +} + +fn f(s: &S) -> S { + S { field: s.field } + //^^^^^^^ error: cannot move `NotCopy` out of reference +} + "#, + ); + } #[test] fn move_by_explicit_deref() { @@ -85,7 +100,7 @@ fn consume(_: X) { fn main() { let a = &X(Y); consume(*a); - //^^^^^^^^^^^ error: cannot move `X` out of reference + //^^ error: cannot move `X` out of reference let a = &X(5); consume(*a); } From d2de4c9411aeebb2bc27c2c737aaf121f48d17cb Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Fri, 28 Feb 2025 10:52:39 +0100 Subject: [PATCH 004/262] change test name to sth meaningful --- src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs | 3 +-- .../crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 9816902fc07b..acd56f02188c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -544,8 +544,7 @@ impl<'ctx> MirLowerCtx<'ctx> { )), } .intern(Interner), - ) - .into(), + ), span: None, }), expr_id.into(), diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs index da8eed29b03d..780271361d72 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs @@ -19,7 +19,7 @@ mod tests { use crate::tests::check_diagnostics; #[test] - fn abc() { + fn operand_field_span_respected() { check_diagnostics( r#" struct NotCopy; From b840942d1dd66d85c631f336b5a57f57f7a79b7f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 8 Apr 2025 15:11:58 +0800 Subject: [PATCH 005/262] Stabilize precise capture syntax in style guide Signed-off-by: xizheyin --- src/doc/style-guide/src/nightly.md | 12 ------------ src/doc/style-guide/src/types.md | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md index d870edf18882..66e7fa3c9f89 100644 --- a/src/doc/style-guide/src/nightly.md +++ b/src/doc/style-guide/src/nightly.md @@ -5,15 +5,3 @@ This chapter documents style and formatting for nightly-only syntax. The rest of Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization. There is no guarantee of the stability of this chapter in contrast to the rest of the style guide. Refer to the style team policy for nightly formatting procedure regarding breaking changes to this chapter. - -### `feature(precise_capturing)` - -A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`. - -``` -fn foo() -> impl Sized + use<'a> {} - -// is formatted analogously to: - -fn foo() -> impl Sized + Use<'a> {} -``` diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md index b7921c8914e4..247f05b57695 100644 --- a/src/doc/style-guide/src/types.md +++ b/src/doc/style-guide/src/types.md @@ -59,3 +59,15 @@ Box< + Debug > ``` + +## Precise capturing bounds + +A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`. + +```rust +fn foo() -> impl Sized + use<'a> {} + +// is formatted analogously to: + +fn foo() -> impl Sized + Use<'a> {} +``` From 11cfc16a60dcca27a1872fa3e83df35d797e8521 Mon Sep 17 00:00:00 2001 From: dianqk Date: Sun, 20 Apr 2025 20:56:41 +0800 Subject: [PATCH 006/262] mir-opt: Use one MirPatch in MatchBranchSimplification --- .../rustc_mir_transform/src/match_branches.rs | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index b37241185c93..8c0c30968990 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -19,30 +19,32 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let typing_env = body.typing_env(tcx); - let mut should_cleanup = false; - for bb_idx in body.basic_blocks.indices() { - match &body.basic_blocks[bb_idx].terminator().kind { + let mut apply_patch = false; + let mut patch = MirPatch::new(body); + for (bb, bb_data) in body.basic_blocks.iter_enumerated() { + match &bb_data.terminator().kind { TerminatorKind::SwitchInt { discr: Operand::Copy(_) | Operand::Move(_), targets, .. // We require that the possible target blocks don't contain this block. - } if !targets.all_targets().contains(&bb_idx) => {} + } if !targets.all_targets().contains(&bb) => {} // Only optimize switch int statements _ => continue, }; - if SimplifyToIf.simplify(tcx, body, bb_idx, typing_env).is_some() { - should_cleanup = true; + if SimplifyToIf.simplify(tcx, body, &mut patch, bb, typing_env).is_some() { + apply_patch = true; continue; } - if SimplifyToExp::default().simplify(tcx, body, bb_idx, typing_env).is_some() { - should_cleanup = true; + if SimplifyToExp::default().simplify(tcx, body, &mut patch, bb, typing_env).is_some() { + apply_patch = true; continue; } } - if should_cleanup { + if apply_patch { + patch.apply(body); simplify_cfg(tcx, body); } } @@ -59,7 +61,8 @@ trait SimplifyMatch<'tcx> { fn simplify( &mut self, tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, + body: &Body<'tcx>, + patch: &mut MirPatch<'tcx>, switch_bb_idx: BasicBlock, typing_env: ty::TypingEnv<'tcx>, ) -> Option<()> { @@ -73,8 +76,6 @@ trait SimplifyMatch<'tcx> { let discr_ty = discr.ty(body.local_decls(), tcx); self.can_simplify(tcx, targets, typing_env, bbs, discr_ty)?; - let mut patch = MirPatch::new(body); - // Take ownership of items now that we know we can optimize. let discr = discr.clone(); @@ -87,19 +88,9 @@ trait SimplifyMatch<'tcx> { let parent_end = Location { block: switch_bb_idx, statement_index }; patch.add_statement(parent_end, StatementKind::StorageLive(discr_local)); patch.add_assign(parent_end, Place::from(discr_local), Rvalue::Use(discr)); - self.new_stmts( - tcx, - targets, - typing_env, - &mut patch, - parent_end, - bbs, - discr_local, - discr_ty, - ); + self.new_stmts(tcx, targets, typing_env, patch, parent_end, bbs, discr_local, discr_ty); patch.add_statement(parent_end, StatementKind::StorageDead(discr_local)); patch.patch_terminator(switch_bb_idx, bbs[first].terminator().kind.clone()); - patch.apply(body); Some(()) } From 5881b7c68b353c3723133c43f209802b3a0c9621 Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 21 Apr 2025 21:46:35 +0800 Subject: [PATCH 007/262] mir-opt: execute MatchBranchSimplification after GVN This can provide more opportunities for MatchBranchSimplification. --- compiler/rustc_mir_transform/src/lib.rs | 3 +-- ...l_unsigned_smaller.Inline.panic-abort.diff | 14 +++++------ ..._unsigned_smaller.Inline.panic-unwind.diff | 14 +++++------ ..._shr_signed_bigger.Inline.panic-abort.diff | 14 +++++------ ...shr_signed_bigger.Inline.panic-unwind.diff | 14 +++++------ ...d.unwrap_unchecked.Inline.panic-abort.diff | 16 ++++++------- ....unwrap_unchecked.Inline.panic-unwind.diff | 16 ++++++------- ...hecked.InstSimplify-after-simplifycfg.diff | 18 +++++++------- ...e_75439.foo.MatchBranchSimplification.diff | 24 ++++++------------- .../matchbr.match1.PreCodegen.after.mir | 13 ++++++++++ tests/mir-opt/pre-codegen/matchbr.rs | 10 ++++++++ ....foo.SimplifyLocals-final.panic-abort.diff | 5 ++-- ...foo.SimplifyLocals-final.panic-unwind.diff | 5 ++-- 13 files changed, 90 insertions(+), 76 deletions(-) create mode 100644 tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir create mode 100644 tests/mir-opt/pre-codegen/matchbr.rs diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 4d74ecddfb05..8b81f0e61797 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -699,8 +699,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Now, we need to shrink the generated MIR. &ref_prop::ReferencePropagation, &sroa::ScalarReplacementOfAggregates, - &match_branches::MatchBranchSimplification, - // inst combine is after MatchBranchSimplification to clean up Ne(_1, false) &multiple_return_terminators::MultipleReturnTerminators, // After simplifycfg, it allows us to discover new opportunities for peephole // optimizations. @@ -709,6 +707,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &dead_store_elimination::DeadStoreElimination::Initial, &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, + &match_branches::MatchBranchSimplification, &dataflow_const_prop::DataflowConstProp, &single_use_consts::SingleUseConsts, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff index f36157a762c2..39ba480d2033 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -8,9 +8,9 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShlUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff index be1b066c6c1b..5a758d357406 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff @@ -8,9 +8,9 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShlUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff index 360687f3c4e7..a0caf141f2d0 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff @@ -8,9 +8,9 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShrUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff index 986df55df037..633089e7b2a2 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff @@ -8,9 +8,9 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShrUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff index 28878736ed7c..a5986a4315a2 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff @@ -10,9 +10,9 @@ + scope 2 { + } + scope 3 (inlined unreachable_unchecked) { -+ let mut _4: bool; -+ let _5: (); ++ let _4: (); + scope 4 (inlined core::ub_checks::check_language_ub) { ++ let mut _5: bool; + scope 5 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -24,7 +24,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable]; + StorageLive(_3); -+ StorageLive(_5); ++ StorageLive(_4); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -34,15 +34,15 @@ + } + + bb2: { -+ StorageLive(_4); -+ _4 = UbChecks(); -+ assume(copy _4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = UbChecks(); ++ assume(copy _5); ++ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { + _0 = move ((_2 as Some).0: T); -+ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff index 27b6bb6a5bb2..12b03a6b6d92 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff @@ -10,9 +10,9 @@ + scope 2 { + } + scope 3 (inlined unreachable_unchecked) { -+ let mut _4: bool; -+ let _5: (); ++ let _4: (); + scope 4 (inlined core::ub_checks::check_language_ub) { ++ let mut _5: bool; + scope 5 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -24,7 +24,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; + StorageLive(_3); -+ StorageLive(_5); ++ StorageLive(_4); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -38,15 +38,15 @@ - bb2 (cleanup): { - resume; + bb2: { -+ StorageLive(_4); -+ _4 = UbChecks(); -+ assume(copy _4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = UbChecks(); ++ assume(copy _5); ++ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { + _0 = move ((_2 as Some).0: T); -+ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff index 5fee9a6733dd..82353a2d5404 100644 --- a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff +++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff @@ -10,9 +10,9 @@ scope 2 { } scope 3 (inlined unreachable_unchecked) { - let mut _4: bool; - let _5: (); + let _4: (); scope 4 (inlined core::ub_checks::check_language_ub) { + let mut _5: bool; scope 5 (inlined core::ub_checks::check_language_ub::runtime) { } } @@ -23,7 +23,7 @@ StorageLive(_2); _2 = copy _1; StorageLive(_3); - StorageLive(_5); + StorageLive(_4); _3 = discriminant(_2); switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -33,16 +33,16 @@ } bb2: { - StorageLive(_4); -- _4 = UbChecks(); -+ _4 = const false; - assume(copy _4); - _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + StorageLive(_5); +- _5 = UbChecks(); ++ _5 = const false; + assume(copy _5); + _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; } bb3: { _0 = move ((_2 as Some).0: i32); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff index 1ab9be966522..d8eace98d556 100644 --- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff +++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -5,23 +5,18 @@ debug bytes => _1; let mut _0: std::option::Option<[u8; 4]>; let _2: [u32; 4]; - let mut _3: [u8; 16]; - let mut _5: [u8; 4]; - let mut _6: u32; + let mut _4: [u8; 4]; scope 1 { debug dwords => _2; scope 2 { - debug ip => _4; - let _4: u32; + debug ip => _3; + let _3: u32; } } bb0: { StorageLive(_2); - StorageLive(_3); - _3 = copy _1; - _2 = move _3 as [u32; 4] (Transmute); - StorageDead(_3); + _2 = copy _1 as [u32; 4] (Transmute); switchInt(copy _2[0 of 4]) -> [0: bb1, otherwise: bb4]; } @@ -34,15 +29,10 @@ } bb3: { + _3 = copy _2[3 of 4]; StorageLive(_4); - _4 = copy _2[3 of 4]; - StorageLive(_5); - StorageLive(_6); - _6 = copy _4; - _5 = move _6 as [u8; 4] (Transmute); - StorageDead(_6); - _0 = Option::<[u8; 4]>::Some(move _5); - StorageDead(_5); + _4 = copy _3 as [u8; 4] (Transmute); + _0 = Option::<[u8; 4]>::Some(move _4); StorageDead(_4); goto -> bb5; } diff --git a/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir new file mode 100644 index 000000000000..3a202728ea91 --- /dev/null +++ b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir @@ -0,0 +1,13 @@ +// MIR for `match1` after PreCodegen + +fn match1(_1: bool, _2: i32, _3: i32) -> i32 { + debug c => _1; + debug v1 => _2; + debug v2 => _3; + let mut _0: i32; + + bb0: { + _0 = Sub(copy _2, copy _3); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/matchbr.rs b/tests/mir-opt/pre-codegen/matchbr.rs new file mode 100644 index 000000000000..1822739da2c7 --- /dev/null +++ b/tests/mir-opt/pre-codegen/matchbr.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +// EMIT_MIR matchbr.match1.PreCodegen.after.mir +pub fn match1(c: bool, v1: i32, v2: i32) -> i32 { + // CHECK-LABEL: fn match1( + // CHECK: bb0: + // CHECK-NEXT: _0 = Sub + // CHECK-NEXT: return; + if c { v1 - v2 } else { v1 - v2 } +} diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff index c363dfcbf70b..ff1bc58524bc 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff @@ -8,6 +8,9 @@ let mut _3: std::option::Option; let mut _4: isize; let mut _5: isize; +- let mut _7: bool; +- let mut _8: u8; +- let mut _9: bool; scope 1 { debug a => _6; let _6: u8; @@ -32,9 +35,7 @@ } bb2: { - StorageLive(_6); _6 = copy (((_1.0: std::option::Option) as Some).0: u8); - StorageDead(_6); goto -> bb3; } diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff index 895b0067d2e6..2c289c664754 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff @@ -8,6 +8,9 @@ let mut _3: std::option::Option; let mut _4: isize; let mut _5: isize; +- let mut _7: bool; +- let mut _8: u8; +- let mut _9: bool; scope 1 { debug a => _6; let _6: u8; @@ -32,9 +35,7 @@ } bb2: { - StorageLive(_6); _6 = copy (((_1.0: std::option::Option) as Some).0: u8); - StorageDead(_6); goto -> bb3; } From d2d844c65dd120a9f3cab15d7519499fcc4130a0 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 22 Apr 2025 00:19:49 +0200 Subject: [PATCH 008/262] Improve rustc_on_unimplemented ui test --- tests/ui/on-unimplemented/bad-annotation.rs | 69 ++++++++++-------- .../ui/on-unimplemented/bad-annotation.stderr | 70 +++++++++++++------ 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/tests/ui/on-unimplemented/bad-annotation.rs b/tests/ui/on-unimplemented/bad-annotation.rs index f2b978657597..32b825ee3cc2 100644 --- a/tests/ui/on-unimplemented/bad-annotation.rs +++ b/tests/ui/on-unimplemented/bad-annotation.rs @@ -1,64 +1,73 @@ -// ignore-tidy-linelength - +#![crate_type = "lib"] #![feature(rustc_attrs)] - #![allow(unused)] #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo -{} +trait Foo {} -#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] +#[rustc_on_unimplemented = "a collection of type `{Self}` cannot \ + be built from an iterator over elements of type `{A}`"] trait MyFromIterator { /// Builds a container with elements from an external iterator. - fn my_from_iter>(iterator: T) -> Self; + fn my_from_iter>(iterator: T) -> Self; } #[rustc_on_unimplemented] //~^ ERROR malformed `rustc_on_unimplemented` attribute -trait BadAnnotation1 -{} +trait NoContent {} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] //~^ ERROR cannot find parameter C on this trait -trait BadAnnotation2 -{} +trait ParameterNotPresent {} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] //~^ ERROR positional format arguments are not allowed here -trait BadAnnotation3 -{} +trait NoPositionalArgs {} -#[rustc_on_unimplemented(lorem="")] +#[rustc_on_unimplemented(lorem = "")] //~^ ERROR this attribute must have a valid -trait BadAnnotation4 {} +trait EmptyMessage {} #[rustc_on_unimplemented(lorem(ipsum(dolor)))] //~^ ERROR this attribute must have a valid -trait BadAnnotation5 {} +trait Invalid {} -#[rustc_on_unimplemented(message="x", message="y")] +#[rustc_on_unimplemented(message = "x", message = "y")] //~^ ERROR this attribute must have a valid -trait BadAnnotation6 {} +trait DuplicateMessage {} -#[rustc_on_unimplemented(message="x", on(desugared, message="y"))] +#[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))] //~^ ERROR this attribute must have a valid -trait BadAnnotation7 {} +trait OnInWrongPosition {} -#[rustc_on_unimplemented(on(), message="y")] +#[rustc_on_unimplemented(on(), message = "y")] //~^ ERROR empty `on`-clause -trait BadAnnotation8 {} +trait NoEmptyOn {} -#[rustc_on_unimplemented(on="x", message="y")] +#[rustc_on_unimplemented(on = "x", message = "y")] //~^ ERROR this attribute must have a valid -trait BadAnnotation9 {} +trait ExpectedPredicateInOn {} -#[rustc_on_unimplemented(on(x="y"), message="y")] -trait BadAnnotation10 {} +#[rustc_on_unimplemented(on(x = "y"), message = "y")] +trait OnWithoutDirectives {} -#[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] +#[rustc_on_unimplemented(on(desugared, on(desugared, message = "x")), message = "y")] //~^ ERROR this attribute must have a valid -trait BadAnnotation11 {} +trait NoNestedOn {} -pub fn main() { -} +// caught by `OnUnimplementedDirective::parse`, *not* `eval_condition` +#[rustc_on_unimplemented(on("y", message = "y"))] +//~^ ERROR invalid `on`-clause +trait UnsupportedLiteral {} + +#[rustc_on_unimplemented(on(not(a, b), message = "y"))] +//~^ ERROR expected 1 cfg-pattern +trait ExpectedOnePattern {} + +#[rustc_on_unimplemented(on(thing::What, message = "y"))] +//~^ ERROR `cfg` predicate key must be an identifier +trait KeyMustBeIdentifier {} + +#[rustc_on_unimplemented(on(thing::What = "value", message = "y"))] +//~^ ERROR `cfg` predicate key must be an identifier +trait KeyMustBeIdentifier2 {} diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index afd737dc85e6..817d3c42cf69 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -1,5 +1,5 @@ error: malformed `rustc_on_unimplemented` attribute input - --> $DIR/bad-annotation.rs:17:1 + --> $DIR/bad-annotation.rs:15:1 | LL | #[rustc_on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,27 +12,27 @@ LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /* | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0230]: cannot find parameter C on this trait - --> $DIR/bad-annotation.rs:22:90 + --> $DIR/bad-annotation.rs:19:90 | LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] | ^ error[E0231]: positional format arguments are not allowed here - --> $DIR/bad-annotation.rs:27:90 + --> $DIR/bad-annotation.rs:23:90 | LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] | ^ error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:32:26 + --> $DIR/bad-annotation.rs:27:26 | -LL | #[rustc_on_unimplemented(lorem="")] - | ^^^^^^^^ expected value here +LL | #[rustc_on_unimplemented(lorem = "")] + | ^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented(message="foo")]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:36:26 + --> $DIR/bad-annotation.rs:31:26 | LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] | ^^^^^^^^^^^^^^^^^^^ expected value here @@ -40,44 +40,68 @@ LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] = note: eg `#[rustc_on_unimplemented(message="foo")]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:40:39 + --> $DIR/bad-annotation.rs:35:41 | -LL | #[rustc_on_unimplemented(message="x", message="y")] - | ^^^^^^^^^^^ expected value here +LL | #[rustc_on_unimplemented(message = "x", message = "y")] + | ^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented(message="foo")]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:44:39 + --> $DIR/bad-annotation.rs:39:41 | -LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here +LL | #[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented(message="foo")]` error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]` - --> $DIR/bad-annotation.rs:48:26 + --> $DIR/bad-annotation.rs:43:26 | -LL | #[rustc_on_unimplemented(on(), message="y")] +LL | #[rustc_on_unimplemented(on(), message = "y")] | ^^^^ empty on-clause here error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:52:26 + --> $DIR/bad-annotation.rs:47:26 | -LL | #[rustc_on_unimplemented(on="x", message="y")] - | ^^^^^^ expected value here +LL | #[rustc_on_unimplemented(on = "x", message = "y")] + | ^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented(message="foo")]` error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:59:40 + --> $DIR/bad-annotation.rs:54:40 | -LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here +LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message = "x")), message = "y")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | = note: eg `#[rustc_on_unimplemented(message="foo")]` -error: aborting due to 10 previous errors +error[E0232]: invalid `on`-clause in `#[rustc_on_unimplemented]` + --> $DIR/bad-annotation.rs:59:26 + | +LL | #[rustc_on_unimplemented(on("y", message = "y"))] + | ^^^^^^^^^^^^^^^^^^^^^^ invalid on-clause here -Some errors have detailed explanations: E0230, E0231, E0232. +error[E0536]: expected 1 cfg-pattern + --> $DIR/bad-annotation.rs:63:29 + | +LL | #[rustc_on_unimplemented(on(not(a, b), message = "y"))] + | ^^^^^^^^^ + +error: `cfg` predicate key must be an identifier + --> $DIR/bad-annotation.rs:67:29 + | +LL | #[rustc_on_unimplemented(on(thing::What, message = "y"))] + | ^^^^^^^^^^^ + +error: `cfg` predicate key must be an identifier + --> $DIR/bad-annotation.rs:71:29 + | +LL | #[rustc_on_unimplemented(on(thing::What = "value", message = "y"))] + | ^^^^^^^^^^^ + +error: aborting due to 14 previous errors + +Some errors have detailed explanations: E0230, E0231, E0232, E0536. For more information about an error, try `rustc --explain E0230`. From 821925e8a476a39bbe71c1601388e677bfd8f410 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 22 Apr 2025 00:44:11 +0200 Subject: [PATCH 009/262] Update browser-ui-test version to 0.20.6 --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 3428dd4826a7..e15121e0f316 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.20.3 \ No newline at end of file +0.20.6 \ No newline at end of file From 934e86b24f8eaf9a52b7c7004fc7a02b1c8310f6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 22 Apr 2025 00:44:24 +0200 Subject: [PATCH 010/262] Unify sidebar buttons to use the same image --- src/librustdoc/html/static/css/rustdoc.css | 43 +++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a6dd06b76ea9..5138c394434c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -55,6 +55,9 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --collapse-arrow-image: url('data:image/svg+xml,'); + --hamburger-image: url('data:image/svg+xml,\ + '); } :root.sans-serif { @@ -2001,9 +2004,11 @@ a.tooltip:hover::after { display: flex; margin-right: 4px; position: fixed; - left: 6px; height: 34px; width: 34px; +} +.hide-sidebar #sidebar-button { + left: 6px; background-color: var(--main-background-color); z-index: 1; } @@ -2019,6 +2024,8 @@ a.tooltip:hover::after { align-items: center; justify-content: center; flex-direction: column; +} +#settings-menu > a, #help-button > a, button#toggle-all-docs { border: 1px solid transparent; border-radius: var(--button-border-radius); color: var(--main-color); @@ -2031,14 +2038,15 @@ a.tooltip:hover::after { min-width: 0; } #sidebar-button > a { - background-color: var(--button-background-color); - border-color: var(--border-color); + background-color: var(--sidebar-background-color); width: 33px; } +#sidebar-button > a:hover, #sidebar-button > a:focus-visible { + background-color: var(--main-background-color); +} #settings-menu > a:hover, #settings-menu > a:focus-visible, #help-button > a:hover, #help-button > a:focus-visible, -#sidebar-button > a:hover, #sidebar-button > a:focus-visible, button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible { border-color: var(--settings-button-border-focus); text-decoration: none; @@ -2402,10 +2410,9 @@ However, it's not needed with smaller screen width because the doc/code block is use hamburger button */ .src #sidebar-button > a::before, .sidebar-menu-toggle::before { /* hamburger button image */ - content: url('data:image/svg+xml,\ - '); + content: var(--hamburger-image); opacity: 0.75; + filter: var(--mobile-sidebar-menu-filter); } .sidebar-menu-toggle:hover::before, .sidebar-menu-toggle:active::before, @@ -2413,17 +2420,6 @@ However, it's not needed with smaller screen width because the doc/code block is opacity: 1; } -/* src sidebar button opens a folder view */ -.src #sidebar-button > a::before { - /* folder image */ - content: url('data:image/svg+xml,\ - \ - \ - '); - opacity: 0.75; -} - /* Media Queries */ /* Make sure all the buttons line wrap at the same time */ @@ -2608,9 +2604,6 @@ in src-script.js and main.js width: 22px; height: 22px; } - .sidebar-menu-toggle::before { - filter: var(--mobile-sidebar-menu-filter); - } .sidebar-menu-toggle:hover { background: var(--main-background-color); } @@ -2668,6 +2661,14 @@ in src-script.js and main.js margin: 0 0 -25px 0; padding: var(--nav-sub-mobile-padding); } + + html:not(.src-sidebar-expanded) .src #sidebar-button > a { + background-color: var(--main-background-color); + } + html:not(.src-sidebar-expanded) .src #sidebar-button > a:hover, + html:not(.src-sidebar-expanded) .src #sidebar-button > a:focus-visible { + background-color: var(--sidebar-background-color); + } } From f7d8558003d5821868feef3fe1858fb422a5afc4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 22 Apr 2025 00:44:44 +0200 Subject: [PATCH 011/262] Add rustdoc-gui test to ensure sidebars share the same image --- tests/rustdoc-gui/sidebar.goml | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 38160cc49d08..9c66b84165f8 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -199,6 +199,42 @@ assert-position-false: (".sidebar-crate > h2 > a", {"x": -3}) drag-and-drop: ((205, 100), (108, 100)) assert-position: (".sidebar-crate > h2 > a", {"x": -3}) +// Check that the mobile sidebar and the source sidebar use the same icon. +store-css: (".mobile-topbar .sidebar-menu-toggle::before", {"content": image_url}) +// Then we go to a source page. +click: ".main-heading .src" +assert-css: ("#sidebar-button a::before", {"content": |image_url|}) +// Check that hover events work as expected. +store-css: ("#sidebar-button a", {"background-color": sidebar_background}) +move-cursor-to: "#sidebar-button a" +store-css: ("#sidebar-button a:hover", {"background-color": sidebar_background_hover}) +assert: |sidebar_background| != |sidebar_background_hover| +click: "#sidebar-button a" +wait-for: "html.src-sidebar-expanded" +assert-css: ("#sidebar-button a:hover", {"background-color": |sidebar_background_hover|}) +move-cursor-to: "#settings-menu" +assert-css: ("#sidebar-button a:not(:hover)", {"background-color": |sidebar_background|}) +// Closing sidebar. +click: "#sidebar-button a" +wait-for: "html:not(.src-sidebar-expanded)" +// Now we check the same when the sidebar button is moved alongside the search. +set-window-size: (500, 500) +store-css: ("#sidebar-button a:hover", {"background-color": not_sidebar_background_hover}) +move-cursor-to: "#settings-menu" +store-css: ("#sidebar-button a:not(:hover)", {"background-color": not_sidebar_background}) +// The sidebar background is supposed to be the same as the main background. +assert-css: ("body", {"background-color": |not_sidebar_background|}) +assert: |not_sidebar_background| != |not_sidebar_background_hover| && |not_sidebar_background| != |sidebar_background| +// The hover background is supposed to be the same as the sidebar background. +assert: |not_sidebar_background_hover| == |sidebar_background| +click: "#sidebar-button a" +wait-for: "html.src-sidebar-expanded" +// And now the background colors are supposed to be the same as the sidebar since the sidebar has +// been open. +assert-css: ("#sidebar-button a:hover", {"background-color": |sidebar_background_hover|}) +move-cursor-to: "h2" +assert-css: ("#sidebar-button a:not(:hover)", {"background-color": |sidebar_background|}) + // Configuration option to show TOC in sidebar. set-local-storage: {"rustdoc-hide-toc": "true"} go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" From 4ff55588d33366d0572c1865b43dec8ac00237b1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Apr 2025 17:37:55 +1100 Subject: [PATCH 012/262] Pass `Analysis` to `visit_*` instead of `Results`. Every `Results` contains an `Analysis`, but these methods only need the `Analysis`. No point passing them more data than they need. --- compiler/rustc_borrowck/src/lib.rs | 6 ++-- .../src/framework/direction.rs | 34 ++++++++++--------- .../src/framework/graphviz.rs | 16 ++++----- .../src/framework/visitor.rs | 8 ++--- compiler/rustc_mir_dataflow/src/points.rs | 4 +-- compiler/rustc_mir_transform/src/coroutine.rs | 4 +-- .../src/dataflow_const_prop.rs | 34 +++++++------------ 7 files changed, 50 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 83a9827e8f81..4ba238696e29 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -705,7 +705,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> { fn visit_after_early_statement_effect( &mut self, - _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, + _analysis: &mut Borrowck<'a, 'tcx>, state: &BorrowckDomain, stmt: &Statement<'tcx>, location: Location, @@ -781,7 +781,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, fn visit_after_early_terminator_effect( &mut self, - _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, + _analysis: &mut Borrowck<'a, 'tcx>, state: &BorrowckDomain, term: &Terminator<'tcx>, loc: Location, @@ -894,7 +894,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, fn visit_after_primary_terminator_effect( &mut self, - _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, + _analysis: &mut Borrowck<'a, 'tcx>, state: &BorrowckDomain, term: &Terminator<'tcx>, loc: Location, diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index b8c26dad59f4..5f34650d460f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -222,17 +222,18 @@ impl Direction for Backward { let loc = Location { block, statement_index: block_data.statements.len() }; let term = block_data.terminator(); - results.analysis.apply_early_terminator_effect(state, term, loc); - vis.visit_after_early_terminator_effect(results, state, term, loc); - results.analysis.apply_primary_terminator_effect(state, term, loc); - vis.visit_after_primary_terminator_effect(results, state, term, loc); + let analysis = &mut results.analysis; + analysis.apply_early_terminator_effect(state, term, loc); + vis.visit_after_early_terminator_effect(analysis, state, term, loc); + analysis.apply_primary_terminator_effect(state, term, loc); + vis.visit_after_primary_terminator_effect(analysis, state, term, loc); for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() { let loc = Location { block, statement_index }; - results.analysis.apply_early_statement_effect(state, stmt, loc); - vis.visit_after_early_statement_effect(results, state, stmt, loc); - results.analysis.apply_primary_statement_effect(state, stmt, loc); - vis.visit_after_primary_statement_effect(results, state, stmt, loc); + analysis.apply_early_statement_effect(state, stmt, loc); + vis.visit_after_early_statement_effect(analysis, state, stmt, loc); + analysis.apply_primary_statement_effect(state, stmt, loc); + vis.visit_after_primary_statement_effect(analysis, state, stmt, loc); } vis.visit_block_start(state); @@ -402,20 +403,21 @@ impl Direction for Forward { vis.visit_block_start(state); + let analysis = &mut results.analysis; for (statement_index, stmt) in block_data.statements.iter().enumerate() { let loc = Location { block, statement_index }; - results.analysis.apply_early_statement_effect(state, stmt, loc); - vis.visit_after_early_statement_effect(results, state, stmt, loc); - results.analysis.apply_primary_statement_effect(state, stmt, loc); - vis.visit_after_primary_statement_effect(results, state, stmt, loc); + analysis.apply_early_statement_effect(state, stmt, loc); + vis.visit_after_early_statement_effect(analysis, state, stmt, loc); + analysis.apply_primary_statement_effect(state, stmt, loc); + vis.visit_after_primary_statement_effect(analysis, state, stmt, loc); } let loc = Location { block, statement_index: block_data.statements.len() }; let term = block_data.terminator(); - results.analysis.apply_early_terminator_effect(state, term, loc); - vis.visit_after_early_terminator_effect(results, state, term, loc); - results.analysis.apply_primary_terminator_effect(state, term, loc); - vis.visit_after_primary_terminator_effect(results, state, term, loc); + analysis.apply_early_terminator_effect(state, term, loc); + vis.visit_after_early_terminator_effect(analysis, state, term, loc); + analysis.apply_primary_terminator_effect(state, term, loc); + vis.visit_after_primary_terminator_effect(analysis, state, term, loc); vis.visit_block_end(state); } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index b5e9a0b89324..14389afff6e7 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -729,49 +729,49 @@ where fn visit_after_early_statement_effect( &mut self, - results: &mut Results<'tcx, A>, + analysis: &mut A, state: &A::Domain, _statement: &mir::Statement<'tcx>, _location: Location, ) { if let Some(before) = self.before.as_mut() { - before.push(diff_pretty(state, &self.prev_state, &results.analysis)); + before.push(diff_pretty(state, &self.prev_state, analysis)); self.prev_state.clone_from(state) } } fn visit_after_primary_statement_effect( &mut self, - results: &mut Results<'tcx, A>, + analysis: &mut A, state: &A::Domain, _statement: &mir::Statement<'tcx>, _location: Location, ) { - self.after.push(diff_pretty(state, &self.prev_state, &results.analysis)); + self.after.push(diff_pretty(state, &self.prev_state, analysis)); self.prev_state.clone_from(state) } fn visit_after_early_terminator_effect( &mut self, - results: &mut Results<'tcx, A>, + analysis: &mut A, state: &A::Domain, _terminator: &mir::Terminator<'tcx>, _location: Location, ) { if let Some(before) = self.before.as_mut() { - before.push(diff_pretty(state, &self.prev_state, &results.analysis)); + before.push(diff_pretty(state, &self.prev_state, analysis)); self.prev_state.clone_from(state) } } fn visit_after_primary_terminator_effect( &mut self, - results: &mut Results<'tcx, A>, + analysis: &mut A, state: &A::Domain, _terminator: &mir::Terminator<'tcx>, _location: Location, ) { - self.after.push(diff_pretty(state, &self.prev_state, &results.analysis)); + self.after.push(diff_pretty(state, &self.prev_state, analysis)); self.prev_state.clone_from(state) } } diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs index c9fdf46c4f5b..07360eb68d18 100644 --- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs @@ -38,7 +38,7 @@ where /// Called after the "early" effect of the given statement is applied to `state`. fn visit_after_early_statement_effect( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, _state: &A::Domain, _statement: &mir::Statement<'tcx>, _location: Location, @@ -48,7 +48,7 @@ where /// Called after the "primary" effect of the given statement is applied to `state`. fn visit_after_primary_statement_effect( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, _state: &A::Domain, _statement: &mir::Statement<'tcx>, _location: Location, @@ -58,7 +58,7 @@ where /// Called after the "early" effect of the given terminator is applied to `state`. fn visit_after_early_terminator_effect( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, _state: &A::Domain, _terminator: &mir::Terminator<'tcx>, _location: Location, @@ -70,7 +70,7 @@ where /// The `call_return_effect` (if one exists) will *not* be applied to `state`. fn visit_after_primary_terminator_effect( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, _state: &A::Domain, _terminator: &mir::Terminator<'tcx>, _location: Location, diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs index 21590ff1bbad..806853ae1e4c 100644 --- a/compiler/rustc_mir_dataflow/src/points.rs +++ b/compiler/rustc_mir_dataflow/src/points.rs @@ -127,7 +127,7 @@ where { fn visit_after_primary_statement_effect<'mir>( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, state: &A::Domain, _statement: &'mir mir::Statement<'tcx>, location: Location, @@ -141,7 +141,7 @@ where fn visit_after_primary_terminator_effect<'mir>( &mut self, - _results: &mut Results<'tcx, A>, + _analysis: &mut A, state: &A::Domain, _terminator: &'mir mir::Terminator<'tcx>, location: Location, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 0eed46c72f99..8174db853995 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -880,7 +880,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage<'a, 'tcx>> { fn visit_after_early_statement_effect( &mut self, - _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>, + _analysis: &mut MaybeRequiresStorage<'a, 'tcx>, state: &DenseBitSet, _statement: &Statement<'tcx>, loc: Location, @@ -890,7 +890,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage<'a, 'tcx>> fn visit_after_early_terminator_effect( &mut self, - _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>, + _analysis: &mut MaybeRequiresStorage<'a, 'tcx>, state: &DenseBitSet, _terminator: &Terminator<'tcx>, loc: Location, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a2103a004d2d..12f76d0db1e8 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -23,7 +23,7 @@ use rustc_mir_dataflow::lattice::{FlatSet, HasBottom}; use rustc_mir_dataflow::value_analysis::{ Map, PlaceIndex, State, TrackElem, ValueOrPlace, debug_with_context, }; -use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor}; +use rustc_mir_dataflow::{Analysis, ResultsVisitor}; use rustc_span::DUMMY_SP; use tracing::{debug, debug_span, instrument}; @@ -959,10 +959,10 @@ fn try_write_constant<'tcx>( } impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> { - #[instrument(level = "trace", skip(self, results, statement))] + #[instrument(level = "trace", skip(self, analysis, statement))] fn visit_after_early_statement_effect( &mut self, - results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>, + analysis: &mut ConstAnalysis<'_, 'tcx>, state: &State>, statement: &Statement<'tcx>, location: Location, @@ -972,8 +972,8 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> OperandCollector { state, visitor: self, - ecx: &mut results.analysis.ecx, - map: &results.analysis.map, + ecx: &mut analysis.ecx, + map: &analysis.map, } .visit_rvalue(rvalue, location); } @@ -981,10 +981,10 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> } } - #[instrument(level = "trace", skip(self, results, statement))] + #[instrument(level = "trace", skip(self, analysis, statement))] fn visit_after_primary_statement_effect( &mut self, - results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>, + analysis: &mut ConstAnalysis<'_, 'tcx>, state: &State>, statement: &Statement<'tcx>, location: Location, @@ -994,12 +994,9 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> // Don't overwrite the assignment if it already uses a constant (to keep the span). } StatementKind::Assign(box (place, _)) => { - if let Some(value) = self.try_make_constant( - &mut results.analysis.ecx, - place, - state, - &results.analysis.map, - ) { + if let Some(value) = + self.try_make_constant(&mut analysis.ecx, place, state, &analysis.map) + { self.patch.assignments.insert(location, value); } } @@ -1009,18 +1006,13 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> fn visit_after_early_terminator_effect( &mut self, - results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>, + analysis: &mut ConstAnalysis<'_, 'tcx>, state: &State>, terminator: &Terminator<'tcx>, location: Location, ) { - OperandCollector { - state, - visitor: self, - ecx: &mut results.analysis.ecx, - map: &results.analysis.map, - } - .visit_terminator(terminator, location); + OperandCollector { state, visitor: self, ecx: &mut analysis.ecx, map: &analysis.map } + .visit_terminator(terminator, location); } } From 92799b6f89d2d9bbfcb9b11d1bac57899d0bc435 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Apr 2025 10:46:20 +1000 Subject: [PATCH 013/262] Separate `Analysis` and `Results`. `Results` contains and `Analysis` and an `EntryStates`. The unfortunate thing about this is that the analysis needs to be mutable everywhere (`&mut Analysis`) which forces the `Results` to be mutable everywhere, even though `EntryStates` is immutable everywhere. To fix this, this commit renames `Results` as `AnalysisAndResults`, renames `EntryStates` as `Results`, and separates the analysis and results as much as possible. (`AnalysisAndResults` doesn't get much use, it's mostly there to facilitate method chaining of `iterate_to_fixpoint`.) `Results` is immutable everywhere, which: - is a bit clearer on how the data is used, - avoids an unnecessary clone of entry states in `locals_live_across_suspend_points`, and - moves the results outside the `RefCell` in Formatter. The commit also reformulates `ResultsHandle` as the generic `CowMut`, which is simpler than `ResultsHandle` because it doesn't need the `'tcx` lifetime and the trait bounds. It also which sits nicely alongside the new use of `Cow` in `ResultsCursor`. --- compiler/rustc_borrowck/src/lib.rs | 20 ++--- .../src/framework/cursor.rs | 78 +++++++++++-------- .../src/framework/direction.rs | 18 ++--- .../src/framework/graphviz.rs | 32 ++++---- .../rustc_mir_dataflow/src/framework/mod.rs | 30 ++++--- .../src/framework/results.rs | 57 +++----------- .../rustc_mir_dataflow/src/framework/tests.rs | 6 +- .../src/framework/visitor.rs | 23 +++++- compiler/rustc_mir_dataflow/src/lib.rs | 4 +- compiler/rustc_mir_dataflow/src/points.rs | 6 +- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 20 ++--- compiler/rustc_mir_transform/src/coroutine.rs | 47 +++++++---- .../src/dataflow_const_prop.rs | 11 +-- compiler/rustc_mir_transform/src/dest_prop.rs | 2 +- .../src/lint_tail_expr_drop_order.rs | 5 +- src/doc/rustc-dev-guide/src/mir/dataflow.md | 3 +- 16 files changed, 188 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4ba238696e29..bf6512ee2332 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -47,7 +47,7 @@ use rustc_mir_dataflow::impls::{ use rustc_mir_dataflow::move_paths::{ InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex, }; -use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results}; +use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results}; use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use smallvec::SmallVec; @@ -461,11 +461,13 @@ fn do_mir_borrowck<'tcx>( // Compute and report region errors, if any. mbcx.report_region_errors(nll_errors); - let mut flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx); + let (mut flow_analysis, flow_entry_states) = + get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx); visit_results( body, traversal::reverse_postorder(body).map(|(bb, _)| bb), - &mut flow_results, + &mut flow_analysis, + &flow_entry_states, &mut mbcx, ); @@ -525,7 +527,7 @@ fn get_flow_results<'a, 'tcx>( move_data: &'a MoveData<'tcx>, borrow_set: &'a BorrowSet<'tcx>, regioncx: &RegionInferenceContext<'tcx>, -) -> Results<'tcx, Borrowck<'a, 'tcx>> { +) -> (Borrowck<'a, 'tcx>, Results) { // We compute these three analyses individually, but them combine them into // a single results so that `mbcx` can visit them all together. let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint( @@ -550,14 +552,14 @@ fn get_flow_results<'a, 'tcx>( ever_inits: ever_inits.analysis, }; - assert_eq!(borrows.entry_states.len(), uninits.entry_states.len()); - assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len()); - let entry_states: EntryStates<'_, Borrowck<'_, '_>> = - itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states) + assert_eq!(borrows.results.len(), uninits.results.len()); + assert_eq!(borrows.results.len(), ever_inits.results.len()); + let results: Results<_> = + itertools::izip!(borrows.results, uninits.results, ever_inits.results) .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits }) .collect(); - Results { analysis, entry_states } + (analysis, results) } pub(crate) struct BorrowckInferCtxt<'tcx> { diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index d5005768b80b..3f6e7a066192 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -1,5 +1,6 @@ //! Random access inspection of the results of a dataflow analysis. +use std::borrow::Cow; use std::cmp::Ordering; use std::ops::{Deref, DerefMut}; @@ -9,38 +10,30 @@ use rustc_middle::mir::{self, BasicBlock, Location}; use super::{Analysis, Direction, Effect, EffectIndex, Results}; -/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either -/// mutable or immutably. This type allows all of the above. It's similar to `Cow`. -pub enum ResultsHandle<'a, 'tcx, A> -where - A: Analysis<'tcx>, -{ - BorrowedMut(&'a mut Results<'tcx, A>), - Owned(Results<'tcx, A>), +/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either +/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow` +/// doesn't allow mutable borrowing. +enum CowMut<'a, T> { + BorrowedMut(&'a mut T), + Owned(T), } -impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A> -where - A: Analysis<'tcx>, -{ - type Target = Results<'tcx, A>; +impl Deref for CowMut<'_, T> { + type Target = T; - fn deref(&self) -> &Results<'tcx, A> { + fn deref(&self) -> &T { match self { - ResultsHandle::BorrowedMut(borrowed) => borrowed, - ResultsHandle::Owned(owned) => owned, + CowMut::BorrowedMut(borrowed) => borrowed, + CowMut::Owned(owned) => owned, } } } -impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A> -where - A: Analysis<'tcx>, -{ - fn deref_mut(&mut self) -> &mut Results<'tcx, A> { +impl DerefMut for CowMut<'_, T> { + fn deref_mut(&mut self) -> &mut T { match self { - ResultsHandle::BorrowedMut(borrowed) => borrowed, - ResultsHandle::Owned(owned) => owned, + CowMut::BorrowedMut(borrowed) => borrowed, + CowMut::Owned(owned) => owned, } } } @@ -60,7 +53,8 @@ where A: Analysis<'tcx>, { body: &'mir mir::Body<'tcx>, - results: ResultsHandle<'mir, 'tcx, A>, + analysis: CowMut<'mir, A>, + results: Cow<'mir, Results>, state: A::Domain, pos: CursorPosition, @@ -88,11 +82,15 @@ where self.body } - /// Returns a new cursor that can inspect `results`. - pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self { - let bottom_value = results.analysis.bottom_value(body); + fn new( + body: &'mir mir::Body<'tcx>, + analysis: CowMut<'mir, A>, + results: Cow<'mir, Results>, + ) -> Self { + let bottom_value = analysis.bottom_value(body); ResultsCursor { body, + analysis, results, // Initialize to the `bottom_value` and set `state_needs_reset` to tell the cursor that @@ -107,6 +105,24 @@ where } } + /// Returns a new cursor that takes ownership of and inspects analysis results. + pub fn new_owning( + body: &'mir mir::Body<'tcx>, + analysis: A, + results: Results, + ) -> Self { + Self::new(body, CowMut::Owned(analysis), Cow::Owned(results)) + } + + /// Returns a new cursor that borrows and inspects analysis results. + pub fn new_borrowing( + body: &'mir mir::Body<'tcx>, + analysis: &'mir mut A, + results: &'mir Results, + ) -> Self { + Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results)) + } + /// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled. #[cfg(test)] pub(crate) fn allow_unreachable(&mut self) { @@ -116,7 +132,7 @@ where /// Returns the `Analysis` used to generate the underlying `Results`. pub fn analysis(&self) -> &A { - &self.results.analysis + &self.analysis } /// Resets the cursor to hold the entry set for the given basic block. @@ -128,7 +144,7 @@ where #[cfg(debug_assertions)] assert!(self.reachable_blocks.contains(block)); - self.state.clone_from(self.results.entry_set_for_block(block)); + self.state.clone_from(&self.results[block]); self.pos = CursorPosition::block_entry(block); self.state_needs_reset = false; } @@ -220,7 +236,7 @@ where let target_effect_index = effect.at_index(target.statement_index); A::Direction::apply_effects_in_range( - &mut self.results.analysis, + &mut *self.analysis, &mut self.state, target.block, block_data, @@ -236,7 +252,7 @@ where /// This can be used, e.g., to apply the call return effect directly to the cursor without /// creating an extra copy of the dataflow state. pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) { - f(&mut self.results.analysis, &mut self.state); + f(&mut self.analysis, &mut self.state); self.state_needs_reset = true; } } diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 5f34650d460f..e955e38ad10f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::{ }; use super::visitor::ResultsVisitor; -use super::{Analysis, Effect, EffectIndex, Results}; +use super::{Analysis, Effect, EffectIndex}; pub trait Direction { const IS_FORWARD: bool; @@ -36,13 +36,13 @@ pub trait Direction { A: Analysis<'tcx>; /// Called by `ResultsVisitor` to recompute the analysis domain values for - /// all locations in a basic block (starting from the entry value stored - /// in `Results`) and to visit them with `vis`. + /// all locations in a basic block (starting from `entry_state` and to + /// visit them with `vis`. fn visit_results_in_block<'mir, 'tcx, A>( state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - results: &mut Results<'tcx, A>, + analysis: &mut A, vis: &mut impl ResultsVisitor<'tcx, A>, ) where A: Analysis<'tcx>; @@ -211,18 +211,15 @@ impl Direction for Backward { state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - results: &mut Results<'tcx, A>, + analysis: &mut A, vis: &mut impl ResultsVisitor<'tcx, A>, ) where A: Analysis<'tcx>, { - state.clone_from(results.entry_set_for_block(block)); - vis.visit_block_end(state); let loc = Location { block, statement_index: block_data.statements.len() }; let term = block_data.terminator(); - let analysis = &mut results.analysis; analysis.apply_early_terminator_effect(state, term, loc); vis.visit_after_early_terminator_effect(analysis, state, term, loc); analysis.apply_primary_terminator_effect(state, term, loc); @@ -394,16 +391,13 @@ impl Direction for Forward { state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - results: &mut Results<'tcx, A>, + analysis: &mut A, vis: &mut impl ResultsVisitor<'tcx, A>, ) where A: Analysis<'tcx>, { - state.clone_from(results.entry_set_for_block(block)); - vis.visit_block_start(state); - let analysis = &mut results.analysis; for (statement_index, stmt) in block_data.statements.iter().enumerate() { let loc = Location { block, statement_index }; analysis.apply_early_statement_effect(state, stmt, loc); diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 14389afff6e7..a7d5422a3d72 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -21,7 +21,9 @@ use tracing::debug; use {rustc_ast as ast, rustc_graphviz as dot}; use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext}; -use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor}; +use super::{ + Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor, visit_results, +}; use crate::errors::{ DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, }; @@ -32,7 +34,8 @@ use crate::errors::{ pub(super) fn write_graphviz_results<'tcx, A>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - results: &mut Results<'tcx, A>, + analysis: &mut A, + results: &Results, pass_name: Option<&'static str>, ) -> std::io::Result<()> where @@ -77,7 +80,7 @@ where let mut buf = Vec::new(); - let graphviz = Formatter::new(body, results, style); + let graphviz = Formatter::new(body, analysis, results, style); let mut render_opts = vec![dot::RenderOption::Fontname(tcx.sess.opts.unstable_opts.graphviz_font.clone())]; if tcx.sess.opts.unstable_opts.graphviz_dark_mode { @@ -203,10 +206,11 @@ where { body: &'mir Body<'tcx>, // The `RefCell` is used because `::node_label` - // takes `&self`, but it needs to modify the results. This is also the + // takes `&self`, but it needs to modify the analysis. This is also the // reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has // the operations that involve the mutation, i.e. within the `borrow_mut`. - results: RefCell<&'mir mut Results<'tcx, A>>, + analysis: RefCell<&'mir mut A>, + results: &'mir Results, style: OutputStyle, reachable: DenseBitSet, } @@ -217,11 +221,12 @@ where { fn new( body: &'mir Body<'tcx>, - results: &'mir mut Results<'tcx, A>, + analysis: &'mir mut A, + results: &'mir Results, style: OutputStyle, ) -> Self { let reachable = traversal::reachable_as_bitset(body); - Formatter { body, results: results.into(), style, reachable } + Formatter { body, analysis: analysis.into(), results, style, reachable } } } @@ -259,12 +264,12 @@ where } fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> { - let mut results = self.results.borrow_mut(); + let analysis = &mut **self.analysis.borrow_mut(); - let diffs = StateDiffCollector::run(self.body, *block, *results, self.style); + let diffs = StateDiffCollector::run(self.body, *block, analysis, self.results, self.style); let mut fmt = BlockFormatter { - cursor: results.as_results_cursor(self.body), + cursor: ResultsCursor::new_borrowing(self.body, analysis, self.results), style: self.style, bg: Background::Light, }; @@ -692,7 +697,8 @@ impl StateDiffCollector { fn run<'tcx, A>( body: &Body<'tcx>, block: BasicBlock, - results: &mut Results<'tcx, A>, + analysis: &mut A, + results: &Results, style: OutputStyle, ) -> Self where @@ -700,12 +706,12 @@ impl StateDiffCollector { D: DebugWithContext, { let mut collector = StateDiffCollector { - prev_state: results.analysis.bottom_value(body), + prev_state: analysis.bottom_value(body), after: vec![], before: (style == OutputStyle::BeforeAndAfter).then_some(vec![]), }; - results.visit_with(body, std::iter::once(block), &mut collector); + visit_results(body, std::iter::once(block), analysis, results, &mut collector); collector } } diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 09f6cdb5c4a7..9cadec100b53 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -58,8 +58,9 @@ mod visitor; pub use self::cursor::ResultsCursor; pub use self::direction::{Backward, Direction, Forward}; pub use self::lattice::{JoinSemiLattice, MaybeReachable}; -pub use self::results::{EntryStates, Results}; -pub use self::visitor::{ResultsVisitor, visit_results}; +pub(crate) use self::results::AnalysisAndResults; +pub use self::results::Results; +pub use self::visitor::{ResultsVisitor, visit_reachable_results, visit_results}; /// Analysis domains are all bitsets of various kinds. This trait holds /// operations needed by all of them. @@ -247,17 +248,15 @@ pub trait Analysis<'tcx> { tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, pass_name: Option<&'static str>, - ) -> Results<'tcx, Self> + ) -> AnalysisAndResults<'tcx, Self> where Self: Sized, Self::Domain: DebugWithContext, { - let mut entry_states = - IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len()); - self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]); + let mut results = IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len()); + self.initialize_start_block(body, &mut results[mir::START_BLOCK]); - if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body) - { + if Self::Direction::IS_BACKWARD && results[mir::START_BLOCK] != self.bottom_value(body) { bug!("`initialize_start_block` is not yet supported for backward dataflow analyses"); } @@ -280,10 +279,9 @@ pub trait Analysis<'tcx> { // every iteration. let mut state = self.bottom_value(body); while let Some(bb) = dirty_queue.pop() { - // Set the state to the entry state of the block. - // This is equivalent to `state = entry_states[bb].clone()`, - // but it saves an allocation, thus improving compile times. - state.clone_from(&entry_states[bb]); + // Set the state to the entry state of the block. This is equivalent to `state = + // results[bb].clone()`, but it saves an allocation, thus improving compile times. + state.clone_from(&results[bb]); Self::Direction::apply_effects_in_block( &mut self, @@ -292,7 +290,7 @@ pub trait Analysis<'tcx> { bb, &body[bb], |target: BasicBlock, state: &Self::Domain| { - let set_changed = entry_states[target].join(state); + let set_changed = results[target].join(state); if set_changed { dirty_queue.insert(target); } @@ -300,16 +298,14 @@ pub trait Analysis<'tcx> { ); } - let mut results = Results { analysis: self, entry_states }; - if tcx.sess.opts.unstable_opts.dump_mir_dataflow { - let res = write_graphviz_results(tcx, body, &mut results, pass_name); + let res = write_graphviz_results(tcx, body, &mut self, &results, pass_name); if let Err(e) = res { error!("Failed to write graphviz dataflow results: {}", e); } } - results + AnalysisAndResults { analysis: self, results } } } diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs index 93dfc06a878a..7b7e981d3a55 100644 --- a/compiler/rustc_mir_dataflow/src/framework/results.rs +++ b/compiler/rustc_mir_dataflow/src/framework/results.rs @@ -1,63 +1,30 @@ //! Dataflow analysis results. use rustc_index::IndexVec; -use rustc_middle::mir::{BasicBlock, Body, traversal}; +use rustc_middle::mir::{BasicBlock, Body}; -use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results}; -use crate::framework::cursor::ResultsHandle; +use super::{Analysis, ResultsCursor}; -pub type EntryStates<'tcx, A> = IndexVec>::Domain>; +/// The results of a dataflow analysis that has converged to fixpoint. It only holds the domain +/// values at the entry of each basic block. Domain values in other parts of the block are +/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls). +pub type Results = IndexVec; -/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the -/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly -/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls). -#[derive(Clone)] -pub struct Results<'tcx, A> +/// Utility type used in a few places where it's convenient to bundle an analysis with its results. +pub struct AnalysisAndResults<'tcx, A> where A: Analysis<'tcx>, { pub analysis: A, - pub entry_states: EntryStates<'tcx, A>, + pub results: Results, } -impl<'tcx, A> Results<'tcx, A> +impl<'tcx, A> AnalysisAndResults<'tcx, A> where A: Analysis<'tcx>, { - /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the - /// `Results` is also used outside the cursor. - pub fn as_results_cursor<'mir>( - &'mir mut self, - body: &'mir Body<'tcx>, - ) -> ResultsCursor<'mir, 'tcx, A> { - ResultsCursor::new(body, ResultsHandle::BorrowedMut(self)) - } - - /// Creates a `ResultsCursor` that takes ownership of the `Results`. + /// Creates a `ResultsCursor` that takes ownership of `self`. pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> { - ResultsCursor::new(body, ResultsHandle::Owned(self)) - } - - /// Gets the dataflow state for the given block. - pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain { - &self.entry_states[block] - } - - pub fn visit_with<'mir>( - &mut self, - body: &'mir Body<'tcx>, - blocks: impl IntoIterator, - vis: &mut impl ResultsVisitor<'tcx, A>, - ) { - visit_results(body, blocks, self, vis) - } - - pub fn visit_reachable_with<'mir>( - &mut self, - body: &'mir Body<'tcx>, - vis: &mut impl ResultsVisitor<'tcx, A>, - ) { - let blocks = traversal::reachable(body); - visit_results(body, blocks.map(|(bb, _)| bb), self, vis) + ResultsCursor::new_owning(body, self.analysis, self.results) } } diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index ae0f1179e6fa..8602bb557652 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -79,7 +79,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { /// /// The `102` in the block's entry set is derived from the basic block index and ensures that the /// expected state is unique across all basic blocks. Remember, it is generated by -/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint. +/// `mock_results`, not from actually running `MockAnalysis` to fixpoint. struct MockAnalysis<'tcx, D> { body: &'tcx mir::Body<'tcx>, dir: PhantomData, @@ -96,7 +96,7 @@ impl MockAnalysis<'_, D> { ret } - fn mock_entry_states(&self) -> IndexVec> { + fn mock_results(&self) -> IndexVec> { let empty = self.bottom_value(self.body); let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks); @@ -255,7 +255,7 @@ fn test_cursor(analysis: MockAnalysis<'_, D>) { let body = analysis.body; let mut cursor = - Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body); + AnalysisAndResults { results: analysis.mock_results(), analysis }.into_results_cursor(body); cursor.allow_unreachable(); diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs index 07360eb68d18..fbb9e4108726 100644 --- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::{self, BasicBlock, Location}; +use rustc_middle::mir::{self, BasicBlock, Location, traversal}; use super::{Analysis, Direction, Results}; @@ -7,12 +7,13 @@ use super::{Analysis, Direction, Results}; pub fn visit_results<'mir, 'tcx, A>( body: &'mir mir::Body<'tcx>, blocks: impl IntoIterator, - results: &mut Results<'tcx, A>, + analysis: &mut A, + results: &Results, vis: &mut impl ResultsVisitor<'tcx, A>, ) where A: Analysis<'tcx>, { - let mut state = results.analysis.bottom_value(body); + let mut state = analysis.bottom_value(body); #[cfg(debug_assertions)] let reachable_blocks = mir::traversal::reachable_as_bitset(body); @@ -22,10 +23,24 @@ pub fn visit_results<'mir, 'tcx, A>( assert!(reachable_blocks.contains(block)); let block_data = &body[block]; - A::Direction::visit_results_in_block(&mut state, block, block_data, results, vis); + state.clone_from(&results[block]); + A::Direction::visit_results_in_block(&mut state, block, block_data, analysis, vis); } } +/// Like `visit_results`, but only for reachable blocks. +pub fn visit_reachable_results<'mir, 'tcx, A>( + body: &'mir mir::Body<'tcx>, + analysis: &mut A, + results: &Results, + vis: &mut impl ResultsVisitor<'tcx, A>, +) where + A: Analysis<'tcx>, +{ + let blocks = traversal::reachable(body).map(|(bb, _)| bb); + visit_results(body, blocks, analysis, results, vis) +} + /// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in /// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain /// locations. diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a0efc623b8e7..420c003fa239 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -18,8 +18,8 @@ pub use self::drop_flag_effects::{ move_path_children_matching, on_all_children_bits, on_lookup_result_bits, }; pub use self::framework::{ - Analysis, Backward, Direction, EntryStates, Forward, GenKill, JoinSemiLattice, MaybeReachable, - Results, ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_results, + Analysis, Backward, Direction, Forward, GenKill, JoinSemiLattice, MaybeReachable, Results, + ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_reachable_results, visit_results, }; use self::move_paths::MoveData; diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs index 806853ae1e4c..70d1a34b5fb1 100644 --- a/compiler/rustc_mir_dataflow/src/points.rs +++ b/compiler/rustc_mir_dataflow/src/points.rs @@ -98,7 +98,8 @@ rustc_index::newtype_index! { pub fn save_as_intervals<'tcx, N, A>( elements: &DenseLocationMap, body: &mir::Body<'tcx>, - mut results: Results<'tcx, A>, + mut analysis: A, + results: Results, ) -> SparseIntervalMatrix where N: Idx, @@ -109,7 +110,8 @@ where visit_results( body, body.basic_blocks.reverse_postorder().iter().copied(), - &mut results, + &mut analysis, + &results, &mut visitor, ); visitor.values diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 399141aa9212..303fc767b9a3 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -39,23 +39,23 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let move_data = MoveData::gather_moves(body, tcx, |_| true); if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() { - let flow_inits = - MaybeInitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(tcx, body, None); - - sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body)); + let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_inits); } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() { let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data) - .iterate_to_fixpoint(tcx, body, None); - - sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body)); + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_uninits); } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() { - let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None); - - sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body)); + let flow_liveness = + MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_liveness); } if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() { diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 8174db853995..18ff70809cbd 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -72,7 +72,9 @@ use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, always_storage_live_locals, }; -use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor}; +use rustc_mir_dataflow::{ + Analysis, Results, ResultsCursor, ResultsVisitor, visit_reachable_results, +}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{Span, sym}; use rustc_target::spec::PanicStrategy; @@ -669,18 +671,29 @@ fn locals_live_across_suspend_points<'tcx>( .iterate_to_fixpoint(tcx, body, None) .into_results_cursor(body); - // Calculate the MIR locals which have been previously - // borrowed (even if they are still active). - let borrowed_locals_results = - MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine")); - - let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body); + // Calculate the MIR locals that have been previously borrowed (even if they are still active). + let borrowed_locals = MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine")); + let mut borrowed_locals_analysis1 = borrowed_locals.analysis; + let mut borrowed_locals_analysis2 = borrowed_locals_analysis1.clone(); // trivial + let borrowed_locals_cursor1 = ResultsCursor::new_borrowing( + body, + &mut borrowed_locals_analysis1, + &borrowed_locals.results, + ); + let mut borrowed_locals_cursor2 = ResultsCursor::new_borrowing( + body, + &mut borrowed_locals_analysis2, + &borrowed_locals.results, + ); // Calculate the MIR locals that we need to keep storage around for. - let mut requires_storage_results = - MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body)) - .iterate_to_fixpoint(tcx, body, None); - let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body); + let mut requires_storage = + MaybeRequiresStorage::new(borrowed_locals_cursor1).iterate_to_fixpoint(tcx, body, None); + let mut requires_storage_cursor = ResultsCursor::new_borrowing( + body, + &mut requires_storage.analysis, + &requires_storage.results, + ); // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = @@ -709,8 +722,8 @@ fn locals_live_across_suspend_points<'tcx>( // If a borrow is converted to a raw reference, we must also assume that it lives // forever. Note that the final liveness is still bounded by the storage liveness // of the local, which happens using the `intersect` operation below. - borrowed_locals_cursor.seek_before_primary_effect(loc); - live_locals.union(borrowed_locals_cursor.get()); + borrowed_locals_cursor2.seek_before_primary_effect(loc); + live_locals.union(borrowed_locals_cursor2.get()); } // Store the storage liveness for later use so we can restore the state @@ -752,7 +765,8 @@ fn locals_live_across_suspend_points<'tcx>( body, &saved_locals, always_live_locals.clone(), - requires_storage_results, + &mut requires_storage.analysis, + &requires_storage.results, ); LivenessInfo { @@ -817,7 +831,8 @@ fn compute_storage_conflicts<'mir, 'tcx>( body: &'mir Body<'tcx>, saved_locals: &'mir CoroutineSavedLocals, always_live_locals: DenseBitSet, - mut requires_storage: Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>, + analysis: &mut MaybeRequiresStorage<'mir, 'tcx>, + results: &Results>, ) -> BitMatrix { assert_eq!(body.local_decls.len(), saved_locals.domain_size()); @@ -837,7 +852,7 @@ fn compute_storage_conflicts<'mir, 'tcx>( eligible_storage_live: DenseBitSet::new_empty(body.local_decls.len()), }; - requires_storage.visit_reachable_with(body, &mut visitor); + visit_reachable_results(body, analysis, results, &mut visitor); let local_conflicts = visitor.local_conflicts; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 12f76d0db1e8..99b95e7312bd 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -23,7 +23,7 @@ use rustc_mir_dataflow::lattice::{FlatSet, HasBottom}; use rustc_mir_dataflow::value_analysis::{ Map, PlaceIndex, State, TrackElem, ValueOrPlace, debug_with_context, }; -use rustc_mir_dataflow::{Analysis, ResultsVisitor}; +use rustc_mir_dataflow::{Analysis, ResultsVisitor, visit_reachable_results}; use rustc_span::DUMMY_SP; use tracing::{debug, debug_span, instrument}; @@ -61,13 +61,14 @@ impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp { let map = Map::new(tcx, body, place_limit); // Perform the actual dataflow analysis. - let analysis = ConstAnalysis::new(tcx, body, map); - let mut results = - debug_span!("analyze").in_scope(|| analysis.iterate_to_fixpoint(tcx, body, None)); + let mut const_ = debug_span!("analyze") + .in_scope(|| ConstAnalysis::new(tcx, body, map).iterate_to_fixpoint(tcx, body, None)); // Collect results and patch the body afterwards. let mut visitor = Collector::new(tcx, &body.local_decls); - debug_span!("collect").in_scope(|| results.visit_reachable_with(body, &mut visitor)); + debug_span!("collect").in_scope(|| { + visit_reachable_results(body, &mut const_.analysis, &const_.results, &mut visitor) + }); let mut patch = visitor.patch; debug_span!("patch").in_scope(|| patch.visit_body_preserves_cfg(body)); } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 7395ad496dbd..4c94a6c524e0 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -171,7 +171,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation { let live = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-DestProp")); let points = DenseLocationMap::new(body); - let mut live = save_as_intervals(&points, body, live); + let mut live = save_as_intervals(&points, body, live.analysis, live.results); // In order to avoid having to collect data for every single pair of locals in the body, we // do not allow doing more than one merge for places that are derived from the same local at diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 537f152938ef..0bf57f27c2ab 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -233,8 +233,9 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< // When we encounter a DROP of some place P we only care // about the drop if `P` may be initialized. let move_data = MoveData::gather_moves(body, tcx, |_| true); - let maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data); - let mut maybe_init = maybe_init.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body); + let mut maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data) + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); let mut block_drop_value_info = IndexVec::from_elem_n(MovePathIndexAtBlock::Unknown, body.basic_blocks.len()); for (&block, candidates) in &bid_per_block { diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md index f31da5ca22ee..85e57dd839b8 100644 --- a/src/doc/rustc-dev-guide/src/mir/dataflow.md +++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md @@ -148,8 +148,7 @@ whereas this code uses [`ResultsCursor`]: ```rust,ignore let mut results = MyAnalysis::new() - .into_engine(tcx, body, def_id) - .iterate_to_fixpoint() + .iterate_to_fixpoint(tcx, body, None); .into_results_cursor(body); // Inspect the fixpoint state immediately before each `Drop` terminator. From 593775a83b80bed7f749a38adea6afa420884434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bernier?= Date: Fri, 18 Apr 2025 00:27:08 -0400 Subject: [PATCH 014/262] Add PGO support to install Enable PGO optimizations when installing rust-analyzer with the --pgo flag. This mirrors functionality already available in dist command, allowing developers to create optimized local builds. Example: cargo xtask install --server --pgo clap-rs/clap PGO code has been extracted to a dedicated module for reuse. --- src/tools/rust-analyzer/xtask/src/dist.rs | 109 ++----------------- src/tools/rust-analyzer/xtask/src/flags.rs | 52 +++++---- src/tools/rust-analyzer/xtask/src/install.rs | 28 ++++- src/tools/rust-analyzer/xtask/src/main.rs | 1 + src/tools/rust-analyzer/xtask/src/pgo.rs | 105 ++++++++++++++++++ src/tools/rust-analyzer/xtask/src/util.rs | 12 ++ 6 files changed, 175 insertions(+), 132 deletions(-) create mode 100644 src/tools/rust-analyzer/xtask/src/pgo.rs diff --git a/src/tools/rust-analyzer/xtask/src/dist.rs b/src/tools/rust-analyzer/xtask/src/dist.rs index b3d6f06b073f..dbfecdbe1121 100644 --- a/src/tools/rust-analyzer/xtask/src/dist.rs +++ b/src/tools/rust-analyzer/xtask/src/dist.rs @@ -1,9 +1,6 @@ use anyhow::Context; use flate2::{Compression, write::GzEncoder}; -use std::env::consts::EXE_EXTENSION; -use std::ffi::OsStr; use std::{ - env, fs::File, io::{self, BufWriter}, path::{Path, PathBuf}, @@ -12,11 +9,11 @@ use time::OffsetDateTime; use xshell::{Cmd, Shell, cmd}; use zip::{DateTime, ZipWriter, write::SimpleFileOptions}; -use crate::flags::PgoTrainingCrate; use crate::{ date_iso, - flags::{self, Malloc}, + flags::{self, Malloc, PgoTrainingCrate}, project_root, + util::detect_target, }; const VERSION_STABLE: &str = "0.3"; @@ -28,7 +25,7 @@ impl flags::Dist { let stable = sh.var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release"; let project_root = project_root(); - let target = Target::get(&project_root); + let target = Target::get(&project_root, sh); let allocator = self.allocator(); let dist = project_root.join("dist"); sh.remove_path(&dist)?; @@ -113,9 +110,9 @@ fn dist_server( let command = if linux_target && zig { "zigbuild" } else { "build" }; let pgo_profile = if let Some(train_crate) = pgo { - Some(gather_pgo_profile( + Some(crate::pgo::gather_pgo_profile( sh, - build_command(sh, command, &target_name, features), + crate::pgo::build_command(sh, command, &target_name, features), &target_name, train_crate, )?) @@ -151,85 +148,6 @@ fn build_command<'a>( ) } -/// Decorates `ra_build_cmd` to add PGO instrumentation, and then runs the PGO instrumented -/// Rust Analyzer on itself to gather a PGO profile. -fn gather_pgo_profile<'a>( - sh: &'a Shell, - ra_build_cmd: Cmd<'a>, - target: &str, - train_crate: PgoTrainingCrate, -) -> anyhow::Result { - let pgo_dir = std::path::absolute("rust-analyzer-pgo")?; - // Clear out any stale profiles - if pgo_dir.is_dir() { - std::fs::remove_dir_all(&pgo_dir)?; - } - std::fs::create_dir_all(&pgo_dir)?; - - // Figure out a path to `llvm-profdata` - let target_libdir = cmd!(sh, "rustc --print=target-libdir") - .read() - .context("cannot resolve target-libdir from rustc")?; - let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin"); - let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION); - - // Build RA with PGO instrumentation - let cmd_gather = - ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap())); - cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?; - - let (train_path, label) = match &train_crate { - PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"), - PgoTrainingCrate::GitHub(repo) => { - (download_crate_for_training(sh, &pgo_dir, repo)?, repo.as_str()) - } - }; - - // Run RA either on itself or on a downloaded crate - eprintln!("Training RA on {label}..."); - cmd!( - sh, - "target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}" - ) - .run() - .context("cannot generate PGO profiles")?; - - // Merge profiles into a single file - let merged_profile = pgo_dir.join("merged.profdata"); - let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| { - let entry = entry.ok()?; - if entry.path().extension() == Some(OsStr::new("profraw")) { - Some(entry.path().to_str().unwrap().to_owned()) - } else { - None - } - }); - cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context( - "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?", - )?; - - Ok(merged_profile) -} - -/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it. -fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, repo: &str) -> anyhow::Result { - let mut it = repo.splitn(2, '@'); - let repo = it.next().unwrap(); - let revision = it.next(); - - // FIXME: switch to `--revision` here around 2035 or so - let revision = - if let Some(revision) = revision { &["--branch", revision] as &[&str] } else { &[] }; - - let normalized_path = repo.replace("/", "-"); - let target_path = pgo_dir.join(normalized_path); - cmd!(sh, "git clone --depth 1 https://github.com/{repo} {revision...} {target_path}") - .run() - .with_context(|| "cannot download PGO training crate from {repo}")?; - - Ok(target_path) -} - fn gzip(src_path: &Path, dest_path: &Path) -> anyhow::Result<()> { let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best()); let mut input = io::BufReader::new(File::open(src_path)?); @@ -283,21 +201,8 @@ struct Target { } impl Target { - fn get(project_root: &Path) -> Self { - let name = match env::var("RA_TARGET") { - Ok(target) => target, - _ => { - if cfg!(target_os = "linux") { - "x86_64-unknown-linux-gnu".to_owned() - } else if cfg!(target_os = "windows") { - "x86_64-pc-windows-msvc".to_owned() - } else if cfg!(target_os = "macos") { - "x86_64-apple-darwin".to_owned() - } else { - panic!("Unsupported OS, maybe try setting RA_TARGET") - } - } - }; + fn get(project_root: &Path, sh: &Shell) -> Self { + let name = detect_target(sh); let (name, libc_suffix) = match name.split_once('.') { Some((l, r)) => (l.to_owned(), Some(r.to_owned())), None => (name, None), diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs index 700806d178c3..2fd471b35c7e 100644 --- a/src/tools/rust-analyzer/xtask/src/flags.rs +++ b/src/tools/rust-analyzer/xtask/src/flags.rs @@ -4,6 +4,25 @@ use std::{fmt, str::FromStr}; use crate::install::{ClientOpt, ProcMacroServerOpt, ServerOpt}; +#[derive(Debug, Clone)] +pub enum PgoTrainingCrate { + // Use RA's own sources for PGO training + RustAnalyzer, + // Download a Rust crate from `https://github.com/{0}` and use it for PGO training. + GitHub(String), +} + +impl FromStr for PgoTrainingCrate { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "rust-analyzer" => Ok(Self::RustAnalyzer), + url => Ok(Self::GitHub(url.to_owned())), + } + } +} + xflags::xflags! { src "./src/flags.rs" @@ -29,6 +48,9 @@ xflags::xflags! { /// build in release with debug info set to 2. optional --dev-rel + + /// Apply PGO optimizations + optional --pgo pgo: PgoTrainingCrate } cmd fuzz-tests {} @@ -109,18 +131,16 @@ pub enum XtaskCmd { Tidy(Tidy), } -#[derive(Debug)] -pub struct Tidy {} - #[derive(Debug)] pub struct Install { pub client: bool, pub code_bin: Option, pub server: bool, - pub proc_macro_server: bool, pub mimalloc: bool, pub jemalloc: bool, + pub proc_macro_server: bool, pub dev_rel: bool, + pub pgo: Option, } #[derive(Debug)] @@ -143,25 +163,6 @@ pub struct RustcPush { pub branch: Option, } -#[derive(Debug)] -pub enum PgoTrainingCrate { - // Use RA's own sources for PGO training - RustAnalyzer, - // Download a Rust crate from `https://github.com/{0}` and use it for PGO training. - GitHub(String), -} - -impl FromStr for PgoTrainingCrate { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - "rust-analyzer" => Ok(Self::RustAnalyzer), - url => Ok(Self::GitHub(url.to_owned())), - } - } -} - #[derive(Debug)] pub struct Dist { pub mimalloc: bool, @@ -195,6 +196,9 @@ pub struct Codegen { pub check: bool, } +#[derive(Debug)] +pub struct Tidy; + impl Xtask { #[allow(dead_code)] pub fn from_env_or_exit() -> Self { @@ -324,7 +328,7 @@ impl Install { } else { Malloc::System }; - Some(ServerOpt { malloc, dev_rel: self.dev_rel }) + Some(ServerOpt { malloc, dev_rel: self.dev_rel, pgo: self.pgo.clone() }) } pub(crate) fn proc_macro_server(&self) -> Option { if !self.proc_macro_server { diff --git a/src/tools/rust-analyzer/xtask/src/install.rs b/src/tools/rust-analyzer/xtask/src/install.rs index 4e2093f0691b..f0cc445dfa23 100644 --- a/src/tools/rust-analyzer/xtask/src/install.rs +++ b/src/tools/rust-analyzer/xtask/src/install.rs @@ -5,7 +5,10 @@ use std::{env, path::PathBuf, str}; use anyhow::{Context, bail, format_err}; use xshell::{Shell, cmd}; -use crate::flags::{self, Malloc}; +use crate::{ + flags::{self, Malloc, PgoTrainingCrate}, + util::detect_target, +}; impl flags::Install { pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> { @@ -35,6 +38,7 @@ const VS_CODES: &[&str] = &["code", "code-exploration", "code-insiders", "codium pub(crate) struct ServerOpt { pub(crate) malloc: Malloc, pub(crate) dev_rel: bool, + pub(crate) pgo: Option, } pub(crate) struct ProcMacroServerOpt { @@ -135,21 +139,33 @@ fn install_server(sh: &Shell, opts: ServerOpt) -> anyhow::Result<()> { let features = opts.malloc.to_features(); let profile = if opts.dev_rel { "dev-rel" } else { "release" }; - let cmd = cmd!( + let mut install_cmd = cmd!( sh, "cargo install --path crates/rust-analyzer --profile={profile} --locked --force --features force-always-assert {features...}" ); - cmd.run()?; + + if let Some(train_crate) = opts.pgo { + let build_cmd = cmd!( + sh, + "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --profile={profile} --locked --features force-always-assert {features...}" + ); + + let target = detect_target(sh); + let profile = crate::pgo::gather_pgo_profile(sh, build_cmd, &target, train_crate)?; + install_cmd = crate::pgo::apply_pgo_to_cmd(install_cmd, &profile); + } + + install_cmd.run()?; Ok(()) } fn install_proc_macro_server(sh: &Shell, opts: ProcMacroServerOpt) -> anyhow::Result<()> { let profile = if opts.dev_rel { "dev-rel" } else { "release" }; - let cmd = cmd!( + cmd!( sh, "cargo +nightly install --path crates/proc-macro-srv-cli --profile={profile} --locked --force --features sysroot-abi" - ); - cmd.run()?; + ).run()?; + Ok(()) } diff --git a/src/tools/rust-analyzer/xtask/src/main.rs b/src/tools/rust-analyzer/xtask/src/main.rs index 52ea896c734d..aaa8d0e1d4d4 100644 --- a/src/tools/rust-analyzer/xtask/src/main.rs +++ b/src/tools/rust-analyzer/xtask/src/main.rs @@ -22,6 +22,7 @@ mod codegen; mod dist; mod install; mod metrics; +mod pgo; mod publish; mod release; mod tidy; diff --git a/src/tools/rust-analyzer/xtask/src/pgo.rs b/src/tools/rust-analyzer/xtask/src/pgo.rs new file mode 100644 index 000000000000..7f7b3311d962 --- /dev/null +++ b/src/tools/rust-analyzer/xtask/src/pgo.rs @@ -0,0 +1,105 @@ +//! PGO (Profile-Guided Optimization) utilities. + +use anyhow::Context; +use std::env::consts::EXE_EXTENSION; +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; +use xshell::{Cmd, Shell, cmd}; + +use crate::flags::PgoTrainingCrate; + +/// Decorates `ra_build_cmd` to add PGO instrumentation, and then runs the PGO instrumented +/// Rust Analyzer on itself to gather a PGO profile. +pub(crate) fn gather_pgo_profile<'a>( + sh: &'a Shell, + ra_build_cmd: Cmd<'a>, + target: &str, + train_crate: PgoTrainingCrate, +) -> anyhow::Result { + let pgo_dir = std::path::absolute("rust-analyzer-pgo")?; + // Clear out any stale profiles + if pgo_dir.is_dir() { + std::fs::remove_dir_all(&pgo_dir)?; + } + std::fs::create_dir_all(&pgo_dir)?; + + // Figure out a path to `llvm-profdata` + let target_libdir = cmd!(sh, "rustc --print=target-libdir") + .read() + .context("cannot resolve target-libdir from rustc")?; + let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin"); + let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION); + + // Build RA with PGO instrumentation + let cmd_gather = + ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap())); + cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?; + + let (train_path, label) = match &train_crate { + PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"), + PgoTrainingCrate::GitHub(repo) => { + (download_crate_for_training(sh, &pgo_dir, repo)?, repo.as_str()) + } + }; + + // Run RA either on itself or on a downloaded crate + eprintln!("Training RA on {label}..."); + cmd!( + sh, + "target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}" + ) + .run() + .context("cannot generate PGO profiles")?; + + // Merge profiles into a single file + let merged_profile = pgo_dir.join("merged.profdata"); + let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| { + let entry = entry.ok()?; + if entry.path().extension() == Some(OsStr::new("profraw")) { + Some(entry.path().to_str().unwrap().to_owned()) + } else { + None + } + }); + cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context( + "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?", + )?; + + Ok(merged_profile) +} + +/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it. +fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, repo: &str) -> anyhow::Result { + let mut it = repo.splitn(2, '@'); + let repo = it.next().unwrap(); + let revision = it.next(); + + // FIXME: switch to `--revision` here around 2035 or so + let revision = + if let Some(revision) = revision { &["--branch", revision] as &[&str] } else { &[] }; + + let normalized_path = repo.replace("/", "-"); + let target_path = pgo_dir.join(normalized_path); + cmd!(sh, "git clone --depth 1 https://github.com/{repo} {revision...} {target_path}") + .run() + .with_context(|| "cannot download PGO training crate from {repo}")?; + + Ok(target_path) +} + +/// Helper function to create a build command for rust-analyzer +pub(crate) fn build_command<'a>( + sh: &'a Shell, + command: &str, + target_name: &str, + features: &[&str], +) -> Cmd<'a> { + cmd!( + sh, + "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release" + ) +} + +pub(crate) fn apply_pgo_to_cmd<'a>(cmd: Cmd<'a>, profile_path: &Path) -> Cmd<'a> { + cmd.env("RUSTFLAGS", format!("-Cprofile-use={}", profile_path.to_str().unwrap())) +} diff --git a/src/tools/rust-analyzer/xtask/src/util.rs b/src/tools/rust-analyzer/xtask/src/util.rs index 39f52938c8c6..a740ad6afdcb 100644 --- a/src/tools/rust-analyzer/xtask/src/util.rs +++ b/src/tools/rust-analyzer/xtask/src/util.rs @@ -1,5 +1,7 @@ use std::path::{Path, PathBuf}; +use xshell::{Shell, cmd}; + pub(crate) fn list_rust_files(dir: &Path) -> Vec { let mut res = list_files(dir); res.retain(|it| { @@ -29,3 +31,13 @@ pub(crate) fn list_files(dir: &Path) -> Vec { } res } + +pub(crate) fn detect_target(sh: &Shell) -> String { + match std::env::var("RA_TARGET") { + Ok(target) => target, + _ => match cmd!(sh, "rustc --print=host-tuple").read() { + Ok(target) => target, + Err(e) => panic!("Failed to detect target: {}\nPlease set RA_TARGET explicitly", e), + }, + } +} From 44232a67c320c8df31e2b82ae15d2ec7c83ec759 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 25 Apr 2025 17:43:12 +0800 Subject: [PATCH 015/262] Add ui test parser/issues/invalid-parse-format-issue-139104.rs Signed-off-by: xizheyin --- .../invalid-parse-format-issue-139104.rs | 8 +++ .../invalid-parse-format-issue-139104.stderr | 66 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/ui/parser/issues/invalid-parse-format-issue-139104.rs create mode 100644 tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs new file mode 100644 index 000000000000..40af62623560 --- /dev/null +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs @@ -0,0 +1,8 @@ +fn main() { + println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: tuple index access isn't supported + println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: tuple index access isn't supported + println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.` + println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.` + println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.` + println!("xxx{ 0", 1.11); //~ ERROR invalid format string: expected `}`, found `0` +} diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr new file mode 100644 index 000000000000..d0a8d0998a48 --- /dev/null +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr @@ -0,0 +1,66 @@ +error: invalid format string: tuple index access isn't supported + --> $DIR/invalid-parse-format-issue-139104.rs:2:16 + | +LL | println!("{foo:_1.4}", foo = 3.14); + | ^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL - println!("{foo:_1.4}", foo = 3.14); +LL + println!("{0}", foo:_1.4, foo = 3.14); + | + +error: invalid format string: tuple index access isn't supported + --> $DIR/invalid-parse-format-issue-139104.rs:3:16 + | +LL | println!("{foo:1.4_1.4}", foo = 3.14); + | ^^^^^^^^^^^ not supported in format string + | +help: consider using a positional formatting argument instead + | +LL - println!("{foo:1.4_1.4}", foo = 3.14); +LL + println!("{0}", foo:1.4_1.4, foo = 3.14); + | + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:4:23 + | +LL | println!("xxx{0:_1.4", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:5:22 + | +LL | println!("{foo:_1.4", foo = 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:6:23 + | +LL | println!("xxx{0:_1.4", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `0` + --> $DIR/invalid-parse-format-issue-139104.rs:7:21 + | +LL | println!("xxx{ 0", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: aborting due to 6 previous errors + From 64867c68f4eb537215e65268903803f44f1fe6b6 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 25 Apr 2025 17:53:40 +0800 Subject: [PATCH 016/262] Check if format argument is identifier to avoid error err-emit Signed-off-by: xizheyin --- compiler/rustc_parse_format/src/lib.rs | 135 ++++++++++++------ .../invalid-parse-format-issue-139104.rs | 10 +- .../invalid-parse-format-issue-139104.stderr | 52 ++----- 3 files changed, 109 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index c59e6cb5c33f..c356a97a55a2 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -100,6 +100,30 @@ pub struct Argument<'a> { pub format: FormatSpec<'a>, } +impl<'a> Argument<'a> { + pub fn is_identifier(&self) -> bool { + matches!(self.position, Position::ArgumentNamed(_)) + && matches!( + self.format, + FormatSpec { + fill: None, + fill_span: None, + align: AlignUnknown, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, + precision: CountImplied, + precision_span: None, + width: CountImplied, + width_span: None, + ty: "", + ty_span: None, + }, + ) + } +} + /// Specification for the formatting of an argument in the format string. #[derive(Copy, Clone, Debug, PartialEq)] pub struct FormatSpec<'a> { @@ -894,52 +918,73 @@ impl<'a> Parser<'a> { } fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) { - if let Some(end) = self.consume_pos('.') { - let byte_pos = self.to_span_index(end); - let start = InnerOffset(byte_pos.0 + 1); - let field = self.argument(start); - // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any - // deeper nesting, or another type of expression, like method calls, are not supported - if !self.consume('}') { - return; - } - if let ArgumentNamed(_) = arg.position { - match field.position { - ArgumentNamed(_) => { - self.errors.insert( - 0, - ParseError { - description: "field access isn't supported".to_string(), - note: None, - label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), - secondary_label: None, - suggestion: Suggestion::UsePositional, - }, - ); - } - ArgumentIs(_) => { - self.errors.insert( - 0, - ParseError { - description: "tuple index access isn't supported".to_string(), - note: None, - label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), - secondary_label: None, - suggestion: Suggestion::UsePositional, - }, - ); - } - _ => {} - }; + // If the argument is an identifier, it may be a field access. + if arg.is_identifier() { + if let Some(end) = self.consume_pos('.') { + let byte_pos = self.to_span_index(end); + let start = InnerOffset(byte_pos.0 + 1); + let field = self.argument(start); + // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any + // deeper nesting, or another type of expression, like method calls, are not supported + if !self.consume('}') { + return; + } + if let ArgumentNamed(_) = arg.position { + match field.position { + ArgumentNamed(_) => { + self.errors.insert( + 0, + ParseError { + description: "field access isn't supported".to_string(), + note: None, + label: "not supported".to_string(), + span: InnerSpan::new( + arg.position_span.start, + field.position_span.end, + ), + secondary_label: None, + suggestion: Suggestion::UsePositional, + }, + ); + } + ArgumentIs(_) => { + self.errors.insert( + 0, + ParseError { + description: "tuple index access isn't supported".to_string(), + note: None, + label: "not supported".to_string(), + span: InnerSpan::new( + arg.position_span.start, + field.position_span.end, + ), + secondary_label: None, + suggestion: Suggestion::UsePositional, + }, + ); + } + _ => {} + }; + } } + } else if matches!(arg.position, ArgumentNamed(_) | ArgumentIs(_)) { + let arg_name = match arg.position { + ArgumentNamed(arg_name) => &format!("`{arg_name}`"), + ArgumentIs(arg_index) => &format!("at index `{arg_index}`"), + _ => unreachable!(), + }; + + self.errors.insert( + 0, + ParseError { + description: format!("invalid format string for argument {}", arg_name), + note: None, + label: format!("invalid format specifier for this argument"), + span: InnerSpan::new(arg.position_span.start, arg.position_span.end), + secondary_label: None, + suggestion: Suggestion::None, + }, + ); } } diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs index 40af62623560..0809235bb6dd 100644 --- a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs @@ -1,8 +1,8 @@ fn main() { - println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: tuple index access isn't supported - println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: tuple index access isn't supported - println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.` - println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.` - println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.` + println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` + println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` + println!("xxx{0:_1.4}", 1.11); //~ ERROR invalid format string: invalid format string for argument at index `0` + println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` + println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: invalid format string for argument at index `0` println!("xxx{ 0", 1.11); //~ ERROR invalid format string: expected `}`, found `0` } diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr index d0a8d0998a48..ceae8d051e5e 100644 --- a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr @@ -1,56 +1,32 @@ -error: invalid format string: tuple index access isn't supported +error: invalid format string: invalid format string for argument `foo` --> $DIR/invalid-parse-format-issue-139104.rs:2:16 | LL | println!("{foo:_1.4}", foo = 3.14); - | ^^^^^^^^ not supported in format string - | -help: consider using a positional formatting argument instead - | -LL - println!("{foo:_1.4}", foo = 3.14); -LL + println!("{0}", foo:_1.4, foo = 3.14); - | + | ^^^ invalid format specifier for this argument in format string -error: invalid format string: tuple index access isn't supported +error: invalid format string: invalid format string for argument `foo` --> $DIR/invalid-parse-format-issue-139104.rs:3:16 | LL | println!("{foo:1.4_1.4}", foo = 3.14); - | ^^^^^^^^^^^ not supported in format string - | -help: consider using a positional formatting argument instead - | -LL - println!("{foo:1.4_1.4}", foo = 3.14); -LL + println!("{0}", foo:1.4_1.4, foo = 3.14); - | + | ^^^ invalid format specifier for this argument in format string -error: invalid format string: expected `}`, found `.` - --> $DIR/invalid-parse-format-issue-139104.rs:4:23 +error: invalid format string: invalid format string for argument at index `0` + --> $DIR/invalid-parse-format-issue-139104.rs:4:19 | -LL | println!("xxx{0:_1.4", 1.11); - | - ^ expected `}` in format string - | | - | because of this opening brace - | - = note: if you intended to print `{`, you can escape it using `{{` +LL | println!("xxx{0:_1.4}", 1.11); + | ^ invalid format specifier for this argument in format string -error: invalid format string: expected `}`, found `.` - --> $DIR/invalid-parse-format-issue-139104.rs:5:22 +error: invalid format string: invalid format string for argument `foo` + --> $DIR/invalid-parse-format-issue-139104.rs:5:16 | LL | println!("{foo:_1.4", foo = 3.14); - | - ^ expected `}` in format string - | | - | because of this opening brace - | - = note: if you intended to print `{`, you can escape it using `{{` + | ^^^ invalid format specifier for this argument in format string -error: invalid format string: expected `}`, found `.` - --> $DIR/invalid-parse-format-issue-139104.rs:6:23 +error: invalid format string: invalid format string for argument at index `0` + --> $DIR/invalid-parse-format-issue-139104.rs:6:19 | LL | println!("xxx{0:_1.4", 1.11); - | - ^ expected `}` in format string - | | - | because of this opening brace - | - = note: if you intended to print `{`, you can escape it using `{{` + | ^ invalid format specifier for this argument in format string error: invalid format string: expected `}`, found `0` --> $DIR/invalid-parse-format-issue-139104.rs:7:21 From 163fb854a2346a26ade9e09ec13ef10a3145ee25 Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 11 Apr 2025 19:57:05 +0530 Subject: [PATCH 017/262] Add the `avx10.1` and `avx10.2` target features --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 3 +++ compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/target_features.rs | 20 +++++++++++++++++++ tests/ui/check-cfg/and-more-diagnostic.rs | 2 +- tests/ui/check-cfg/target_feature.stderr | 2 ++ .../feature-gate-avx10_target_feature.rs | 6 ++++++ .../feature-gate-avx10_target_feature.stderr | 13 ++++++++++++ 8 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/ui/feature-gates/feature-gate-avx10_target_feature.rs create mode 100644 tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 36e35f81392b..8afd34829e31 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -294,6 +294,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option None, + ("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")), + ("x86", "avx10.2") if get_version().0 < 20 => None, + ("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")), (_, s) => Some(LLVMFeature::new(s)), } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index cbc121e3632a..490641b9884a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -389,6 +389,8 @@ declare_features! ( (unstable, async_for_loop, "1.77.0", Some(118898)), /// Allows `async` trait bound modifier. (unstable, async_trait_bounds, "1.85.0", Some(62290)), + /// Allows using Intel AVX10 target features and intrinsics + (unstable, avx10_target_feature, "CURRENT_RUSTC_VERSION", Some(138843)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 32a5aff0cb32..4483cf14c619 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -540,6 +540,7 @@ symbols! { autodiff, automatically_derived, avx, + avx10_target_feature, avx512_target_feature, avx512bw, avx512f, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 69c8b9119ab2..6fa8af2e0fff 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -391,6 +391,26 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]), ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("avx", Stable, &["sse4.2"]), + ( + "avx10.1", + Unstable(sym::avx10_target_feature), + &[ + "avx512bf16", + "avx512bitalg", + "avx512bw", + "avx512cd", + "avx512dq", + "avx512f", + "avx512fp16", + "avx512ifma", + "avx512vbmi", + "avx512vbmi2", + "avx512vl", + "avx512vnni", + "avx512vpopcntdq", + ], + ), + ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]), ("avx2", Stable, &["avx"]), ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]), ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]), diff --git a/tests/ui/check-cfg/and-more-diagnostic.rs b/tests/ui/check-cfg/and-more-diagnostic.rs index 977f55e8a6d1..5422829c5b31 100644 --- a/tests/ui/check-cfg/and-more-diagnostic.rs +++ b/tests/ui/check-cfg/and-more-diagnostic.rs @@ -5,7 +5,7 @@ //@ no-auto-check-cfg //@ compile-flags: --check-cfg=cfg() //@ normalize-stderr: "and \d+ more" -> "and X more" -//@ normalize-stderr: "`[a-zA-Z0-9_-]+`" -> "`xxx`" +//@ normalize-stderr: "`[a-zA-Z0-9_\.-]+`" -> "`xxx`" fn main() { cfg!(target_feature = "zebra"); diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 4f7b8345e86a..9d072d27255f 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -29,6 +29,8 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `amx-transpose` `atomics` `avx` +`avx10.1` +`avx10.2` `avx2` `avx512bf16` `avx512bitalg` diff --git a/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs b/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs new file mode 100644 index 000000000000..8557e67d1f41 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs @@ -0,0 +1,6 @@ +//@ only-x86_64 +#[target_feature(enable = "avx10.1")] +//~^ ERROR: currently unstable +unsafe fn foo() {} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr b/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr new file mode 100644 index 000000000000..e45ea3524ca7 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr @@ -0,0 +1,13 @@ +error[E0658]: the target feature `avx10.1` is currently unstable + --> $DIR/feature-gate-avx10_target_feature.rs:2:18 + | +LL | #[target_feature(enable = "avx10.1")] + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #138843 for more information + = help: add `#![feature(avx10_target_feature)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From 2b701e00f12e41ed2d9a75b6fd14fb20640d159d Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 26 Apr 2025 21:10:43 +0300 Subject: [PATCH 018/262] Escape raw names in labels properly --- .../rust-analyzer/crates/hir-expand/src/name.rs | 15 ++++++++++----- .../ide-completion/src/tests/expression.rs | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index d43ef38f291d..37290edae4ec 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -191,7 +191,7 @@ impl Name { // FIXME: Remove this in favor of `display`, see fixme on `as_str` #[doc(hidden)] pub fn display_no_db(&self, edition: Edition) -> impl fmt::Display + '_ { - Display { name: self, needs_escaping: is_raw_identifier(self.symbol.as_str(), edition) } + Display { name: self, edition } } pub fn symbol(&self) -> &Symbol { @@ -201,15 +201,20 @@ impl Name { struct Display<'a> { name: &'a Name, - needs_escaping: bool, + edition: Edition, } impl fmt::Display for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.needs_escaping { - write!(f, "r#")?; + let mut symbol = self.name.symbol.as_str(); + if let Some(s) = symbol.strip_prefix('\'') { + f.write_str("'")?; + symbol = s; } - fmt::Display::fmt(self.name.symbol.as_str(), f) + if is_raw_identifier(symbol, self.edition) { + f.write_str("r#")?; + } + f.write_str(symbol) } } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index b30ac43bf8fb..27d6bc7b14f2 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs @@ -2110,3 +2110,19 @@ fn foo() { "#]], ); } + +#[test] +fn escaped_label() { + check( + r#" +fn main() { + 'r#break: { + break '$0; + } +} + "#, + expect![[r#" + lb 'r#break + "#]], + ); +} From 8118676a08fa00ce5a8ffac6427c95c4df9a2e9b Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 26 Apr 2025 21:20:43 +0300 Subject: [PATCH 019/262] Don't escape `'static` As it is a valid lifetime without escaping. It does need to be escaped as a label, but we have no way to distinguish that. --- src/tools/rust-analyzer/crates/hir-expand/src/name.rs | 8 ++++++++ .../crates/ide-completion/src/completions/lifetime.rs | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 37290edae4ec..217d991d110d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -207,6 +207,14 @@ struct Display<'a> { impl fmt::Display for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut symbol = self.name.symbol.as_str(); + + if symbol == "'static" { + // FIXME: '`static` can also be a label, and there it does need escaping. + // But knowing where it is will require adding a parameter to `display()`, + // and that is an infectious change. + return f.write_str(symbol); + } + if let Some(s) = symbol.strip_prefix('\'') { f.write_str("'")?; symbol = s; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs index b02f079b7213..8902cd09cec0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs @@ -116,13 +116,13 @@ fn foo<'lifetime>(foo: &'a$0) {} check( r#" struct Foo; -impl<'impl> Foo { +impl<'r#impl> Foo { fn foo<'func>(&'a$0 self) {} } "#, expect![[r#" lt 'func - lt 'impl + lt 'r#impl lt 'static "#]], ); From 8290766bbee6a9ce384d0e7527c46001392ed423 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 27 Apr 2025 07:14:04 +0000 Subject: [PATCH 020/262] bypass linker configuration and cross target check on `x check` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/cargo.rs | 2 +- src/bootstrap/src/utils/cc_detect.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index e4503b264562..149a19d9d88c 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -114,7 +114,7 @@ impl Cargo { match cmd_kind { // No need to configure the target linker for these command types, // as they don't invoke rustc at all. - Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {} + Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {} _ => { cargo.configure_linker(builder); } diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 147b009d3f47..ceac24d4315c 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -96,6 +96,7 @@ pub fn find(build: &Build) { let targets: HashSet<_> = match build.config.cmd { // We don't need to check cross targets for these commands. crate::Subcommand::Clean { .. } + | crate::Subcommand::Check { .. } | crate::Subcommand::Suggest { .. } | crate::Subcommand::Format { .. } | crate::Subcommand::Setup { .. } => { From 7669d5011977eef757bb4cd9437b6aef50f4b3f6 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 28 Apr 2025 06:49:38 +0300 Subject: [PATCH 021/262] add a FIXME Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/cargo.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 149a19d9d88c..5d3f7c9cc76b 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -112,8 +112,7 @@ impl Cargo { let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind); match cmd_kind { - // No need to configure the target linker for these command types, - // as they don't invoke rustc at all. + // No need to configure the target linker for these command types. Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {} _ => { cargo.configure_linker(builder); @@ -205,6 +204,8 @@ impl Cargo { self } + // FIXME(onur-ozkan): Add coverage to make sure modifications to this function + // doesn't cause cache invalidations (e.g., #130108). fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo { let target = self.target; let compiler = self.compiler; From 7e064c3072adff6e97581a34393ca6abedd4a335 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 28 Apr 2025 10:39:36 +0200 Subject: [PATCH 022/262] Add expression fill mode variant for filling with underscore expressions --- .../hir-def/src/nameres/mod_resolution.rs | 2 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 3 +- .../crates/hir-expand/src/lib.rs | 3 +- .../crates/ide-assists/src/assist_config.rs | 3 +- .../src/handlers/add_missing_impl_members.rs | 1 + .../src/handlers/add_missing_match_arms.rs | 23 +++++++- .../src/handlers/destructure_tuple_binding.rs | 2 +- .../src/handlers/generate_function.rs | 19 ++++++- .../replace_derive_with_manual_impl.rs | 15 +++-- .../crates/ide-assists/src/tests.rs | 5 ++ .../crates/ide-assists/src/utils.rs | 16 +++++- .../crates/ide-completion/src/item.rs | 2 +- .../crates/ide-db/src/assists.rs | 12 ++++ .../src/handlers/missing_fields.rs | 15 +++-- .../src/handlers/typed_hole.rs | 42 ++++++++++---- .../crates/ide-diagnostics/src/lib.rs | 13 +---- .../crates/ide-diagnostics/src/tests.rs | 55 ++----------------- .../rust-analyzer/crates/ide/src/doc_links.rs | 2 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 5 +- .../rust-analyzer/crates/ide/src/moniker.rs | 2 +- .../rust-analyzer/crates/ide/src/status.rs | 4 +- .../crates/ide/src/view_crate_graph.rs | 2 +- .../crates/proc-macro-srv/build.rs | 2 +- .../query-group-macro/tests/logger_db.rs | 2 +- .../rust-analyzer/src/cli/analysis_stats.rs | 10 ++-- .../crates/rust-analyzer/src/cli/scip.rs | 6 +- .../crates/rust-analyzer/src/config.rs | 16 ++++-- .../crates/syntax/src/ast/make.rs | 3 + src/tools/rust-analyzer/crates/tt/src/lib.rs | 6 +- .../xtask/src/codegen/grammar.rs | 2 +- .../xtask/src/codegen/parser_inline_tests.rs | 4 +- 31 files changed, 172 insertions(+), 125 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index d6c9f5a00c91..0c50f13edfb6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -86,7 +86,7 @@ impl ModDir { let dir_path = if root_dir_owner { DirPath::empty() } else { - DirPath::new(format!("{}/", name)) + DirPath::new(format!("{name}/")) }; if let Some(mod_dir) = self.child(dir_path, !root_dir_owner) { return Ok(( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 29b7b33fd0fb..2219a55a84be 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -752,8 +752,7 @@ fn check_tt_count(tt: &tt::TopSubtree) -> Result<(), ExpandResult<()>> { err: Some(ExpandError::other( tt.delimiter.open, format!( - "macro invocation exceeds token limit: produced {} tokens, limit is {}", - count, TOKEN_LIMIT, + "macro invocation exceeds token limit: produced {count} tokens, limit is {TOKEN_LIMIT}", ), )), }) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index f0a9a2ad52c8..ad35f7000a14 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -206,8 +206,7 @@ impl ExpandErrorKind { }, None => RenderedExpandError { message: format!( - "internal error: proc-macro map is missing error entry for crate {:?}", - def_crate + "internal error: proc-macro map is missing error entry for crate {def_crate:?}" ), error: true, kind: RenderedExpandError::GENERAL_KIND, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs index 2de0013bb126..fb569f8cdae0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs @@ -5,7 +5,7 @@ //! assists if we are allowed to. use hir::ImportPathConfig; -use ide_db::{SnippetCap, imports::insert_use::InsertUseConfig}; +use ide_db::{SnippetCap, assists::ExprFillDefaultMode, imports::insert_use::InsertUseConfig}; use crate::AssistKind; @@ -21,6 +21,7 @@ pub struct AssistConfig { pub term_search_fuel: u64, pub term_search_borrowck: bool, pub code_action_grouping: bool, + pub expr_fill_default: ExprFillDefaultMode, } impl AssistConfig { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 887ec5aeec9a..6a55f39e6934 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -150,6 +150,7 @@ fn add_missing_impl_members_inner( let new_impl_def = edit.make_mut(impl_def.clone()); let first_new_item = add_trait_assoc_items_to_impl( &ctx.sema, + ctx.config, &missing_items, trait_, &new_impl_def, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 8c1c83e3f716..05d21cb97933 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -3,6 +3,7 @@ use std::iter::{self, Peekable}; use either::Either; use hir::{Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics, sym}; use ide_db::RootDatabase; +use ide_db::assists::ExprFillDefaultMode; use ide_db::syntax_helpers::suggest_name; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; @@ -216,7 +217,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) // filter out hidden patterns because they're handled by the catch-all arm !hidden }) - .map(|(pat, _)| make.match_arm(pat, None, make::ext::expr_todo())); + .map(|(pat, _)| { + make.match_arm( + pat, + None, + match ctx.config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }, + ) + }); let mut arms: Vec<_> = match_arm_list .arms() @@ -246,7 +257,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) if needs_catch_all_arm && !has_catch_all_arm { cov_mark::hit!(added_wildcard_pattern); - let arm = make.match_arm(make.wildcard_pat().into(), None, make::ext::expr_todo()); + let arm = make.match_arm( + make.wildcard_pat().into(), + None, + match ctx.config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }, + ); arms.push(arm); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index adf0f0997b39..f09389f8302f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs @@ -142,7 +142,7 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option name, - None => name_generator.suggest_name(&format!("_{}", id)), + None => name_generator.suggest_name(&format!("_{id}")), } .to_string() }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 824380253ae5..ba2b84a42c75 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -4,6 +4,7 @@ use hir::{ }; use ide_db::{ FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, + assists::ExprFillDefaultMode, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::is_editable_crate, @@ -276,7 +277,11 @@ impl FunctionBuilder { target_module, &mut necessary_generic_params, ); - let placeholder_expr = make::ext::expr_todo(); + let placeholder_expr = match ctx.config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }; fn_body = make::block_expr(vec![], Some(placeholder_expr)); }; @@ -331,7 +336,11 @@ impl FunctionBuilder { let (generic_param_list, where_clause) = fn_generic_params(ctx, necessary_generic_params, &target)?; - let placeholder_expr = make::ext::expr_todo(); + let placeholder_expr = match ctx.config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }; let fn_body = make::block_expr(vec![], Some(placeholder_expr)); Some(Self { @@ -444,7 +453,11 @@ fn make_fn_body_as_new_function( let adt_info = adt_info.as_ref()?; let path_self = make::ext::ident_path("Self"); - let placeholder_expr = make::ext::expr_todo(); + let placeholder_expr = match ctx.config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }; let tail_expr = if let Some(strukt) = adt_info.adt.as_struct() { match strukt.kind(ctx.db()) { StructKind::Record => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 6dcdf5edbd63..806c8fba9ea4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -9,7 +9,7 @@ use syntax::{ }; use crate::{ - AssistId, + AssistConfig, AssistId, assist_context::{AssistContext, Assists, SourceChangeBuilder}, utils::{ DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items, @@ -128,8 +128,14 @@ fn add_assist( acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| { let insert_after = ted::Position::after(builder.make_mut(adt.clone()).syntax()); let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false); - let impl_def_with_items = - impl_def_from_trait(&ctx.sema, adt, &annotated_name, trait_, replace_trait_path); + let impl_def_with_items = impl_def_from_trait( + &ctx.sema, + ctx.config, + adt, + &annotated_name, + trait_, + replace_trait_path, + ); update_attribute(builder, old_derives, old_tree, old_trait_path, attr); let trait_path = make::ty_path(replace_trait_path.clone()); @@ -217,6 +223,7 @@ fn add_assist( fn impl_def_from_trait( sema: &hir::Semantics<'_, ide_db::RootDatabase>, + config: &AssistConfig, adt: &ast::Adt, annotated_name: &ast::Name, trait_: Option, @@ -241,7 +248,7 @@ fn impl_def_from_trait( let impl_def = generate_trait_impl(adt, make::ty_path(trait_path.clone())); let first_assoc_item = - add_trait_assoc_items_to_impl(sema, &trait_items, trait_, &impl_def, &target_scope); + add_trait_assoc_items_to_impl(sema, config, &trait_items, trait_, &impl_def, &target_scope); // Generate a default `impl` function body for the derived trait. if let ast::AssocItem::Fn(ref func) = first_assoc_item { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 0593e6930dca..5e6889792db6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -4,6 +4,7 @@ use expect_test::expect; use hir::Semantics; use ide_db::{ EditionedFileId, FileRange, RootDatabase, SnippetCap, + assists::ExprFillDefaultMode, base_db::SourceDatabase, imports::insert_use::{ImportGranularity, InsertUseConfig}, source_change::FileSystemEdit, @@ -35,6 +36,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { term_search_fuel: 400, term_search_borrowck: true, code_action_grouping: true, + expr_fill_default: ExprFillDefaultMode::Todo, }; pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig { @@ -54,6 +56,7 @@ pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig { term_search_fuel: 400, term_search_borrowck: true, code_action_grouping: false, + expr_fill_default: ExprFillDefaultMode::Todo, }; pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig { @@ -73,6 +76,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig { term_search_fuel: 400, term_search_borrowck: true, code_action_grouping: true, + expr_fill_default: ExprFillDefaultMode::Todo, }; pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig { @@ -92,6 +96,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig { term_search_fuel: 400, term_search_borrowck: true, code_action_grouping: true, + expr_fill_default: ExprFillDefaultMode::Todo, }; pub(crate) fn with_single_file(text: &str) -> (RootDatabase, EditionedFileId) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 0471998f0b14..ef6914fda1d5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -8,6 +8,7 @@ use hir::{ }; use ide_db::{ RootDatabase, + assists::ExprFillDefaultMode, famous_defs::FamousDefs, path_transform::PathTransform, syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion}, @@ -27,7 +28,10 @@ use syntax::{ ted, }; -use crate::assist_context::{AssistContext, SourceChangeBuilder}; +use crate::{ + AssistConfig, + assist_context::{AssistContext, SourceChangeBuilder}, +}; mod gen_trait_fn_body; pub(crate) mod ref_field_expr; @@ -174,6 +178,7 @@ pub fn filter_assoc_items( /// inserted. pub fn add_trait_assoc_items_to_impl( sema: &Semantics<'_, RootDatabase>, + config: &AssistConfig, original_items: &[InFile], trait_: hir::Trait, impl_: &ast::Impl, @@ -219,7 +224,14 @@ pub fn add_trait_assoc_items_to_impl( match &item { ast::AssocItem::Fn(fn_) if fn_.body().is_none() => { let body = AstNodeEdit::indent( - &make::block_expr(None, Some(make::ext::expr_todo())), + &make::block_expr( + None, + Some(match config.expr_fill_default { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => make::ext::expr_todo(), + }), + ), new_indent_level, ); ted::replace(fn_.get_or_create_body().syntax(), body.clone_for_update().syntax()) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index e208b9fd41ae..19cdef30bd96 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -135,7 +135,7 @@ impl fmt::Debug for CompletionItem { }, CompletionItemRefMode::Dereference => "*", }; - s.field("ref_match", &format!("{}@{offset:?}", prefix)); + s.field("ref_match", &format!("{prefix}@{offset:?}")); } if self.trigger_call_info { s.field("trigger_call_info", &true); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs index 90ae4a3b5b3a..384eb57c0fd5 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs @@ -169,3 +169,15 @@ impl AssistResolveStrategy { #[derive(Clone, Debug)] pub struct GroupLabel(pub String); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ExprFillDefaultMode { + Todo, + Default, + Underscore, +} +impl Default for ExprFillDefaultMode { + fn default() -> Self { + Self::Todo + } +} diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index 6b02111016c0..9aea2b1056d2 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -5,9 +5,13 @@ use hir::{ sym, }; use ide_db::{ - FxHashMap, assists::Assist, famous_defs::FamousDefs, - imports::import_assets::item_for_path_search, source_change::SourceChange, - syntax_helpers::tree_diff::diff, text_edit::TextEdit, + FxHashMap, + assists::{Assist, ExprFillDefaultMode}, + famous_defs::FamousDefs, + imports::import_assets::item_for_path_search, + source_change::SourceChange, + syntax_helpers::tree_diff::diff, + text_edit::TextEdit, use_trivial_constructor::use_trivial_constructor, }; use stdx::format_to; @@ -102,8 +106,9 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option make::ext::expr_todo(), - crate::ExprFillDefaultMode::Default => { + ExprFillDefaultMode::Todo => make::ext::expr_todo(), + ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), + ExprFillDefaultMode::Default => { get_default_constructor(ctx, d, ty).unwrap_or_else(make::ext::expr_todo) } }; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 277aff2e08f4..1e7f00c23313 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -1,3 +1,5 @@ +use std::ops::Not; + use hir::{ ClosureStyle, HirDisplay, ImportPathConfig, db::ExpandDatabase, @@ -60,9 +62,13 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option let mut formatter = |_: &hir::Type| String::from("_"); - let assists: Vec = paths + let assists: Vec = d + .expected + .is_unknown() + .not() + .then(|| "todo!()".to_owned()) .into_iter() - .filter_map(|path| { + .chain(paths.into_iter().filter_map(|path| { path.gen_source_code( &scope, &mut formatter, @@ -75,7 +81,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option ctx.display_target, ) .ok() - }) + })) .unique() .map(|code| Assist { id: AssistId::quick_fix("typed-hole"), @@ -95,9 +101,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option #[cfg(test)] mod tests { - use crate::tests::{ - check_diagnostics, check_fixes_unordered, check_has_fix, check_has_single_fix, - }; + use crate::tests::{check_diagnostics, check_fixes_unordered, check_has_fix}; #[test] fn unknown() { @@ -119,9 +123,9 @@ fn main() { if _ {} //^ 💡 error: invalid `_` expression, expected type `bool` let _: fn() -> i32 = _; - //^ error: invalid `_` expression, expected type `fn() -> i32` + //^ 💡 error: invalid `_` expression, expected type `fn() -> i32` let _: fn() -> () = _; // FIXME: This should trigger an assist because `main` matches via *coercion* - //^ error: invalid `_` expression, expected type `fn()` + //^ 💡 error: invalid `_` expression, expected type `fn()` } "#, ); @@ -147,7 +151,7 @@ fn main() { fn main() { let mut x = t(); x = _; - //^ error: invalid `_` expression, expected type `&str` + //^ 💡 error: invalid `_` expression, expected type `&str` x = ""; } fn t() -> T { loop {} } @@ -308,7 +312,7 @@ fn main() { #[test] fn ignore_impl_func_with_incorrect_return() { - check_has_single_fix( + check_fixes_unordered( r#" struct Bar {} trait Foo { @@ -323,7 +327,8 @@ fn main() { let a: i32 = 1; let c: Bar = _$0; }"#, - r#" + vec![ + r#" struct Bar {} trait Foo { type Res; @@ -337,6 +342,21 @@ fn main() { let a: i32 = 1; let c: Bar = Bar { }; }"#, + r#" +struct Bar {} +trait Foo { + type Res; + fn foo(&self) -> Self::Res; +} +impl Foo for i32 { + type Res = Self; + fn foo(&self) -> Self::Res { 1 } +} +fn main() { + let a: i32 = 1; + let c: Bar = todo!(); +}"#, + ], ); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 11efedd8a59d..607721d611d7 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -92,7 +92,7 @@ use hir::{ }; use ide_db::{ EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, - assists::{Assist, AssistId, AssistResolveStrategy}, + assists::{Assist, AssistId, AssistResolveStrategy, ExprFillDefaultMode}, base_db::{ReleaseChannel, RootQueryDb as _}, generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup}, imports::insert_use::InsertUseConfig, @@ -219,17 +219,6 @@ impl Diagnostic { } } -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum ExprFillDefaultMode { - Todo, - Default, -} -impl Default for ExprFillDefaultMode { - fn default() -> Self { - Self::Todo - } -} - #[derive(Debug, Clone)] pub struct DiagnosticsConfig { /// Whether native diagnostics are enabled. diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs index 13d08d46dedd..4e4bd47e1c2f 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs @@ -3,14 +3,16 @@ mod overly_long_real_world_cases; use ide_db::{ - LineIndexDatabase, RootDatabase, assists::AssistResolveStrategy, base_db::SourceDatabase, + LineIndexDatabase, RootDatabase, + assists::{AssistResolveStrategy, ExprFillDefaultMode}, + base_db::SourceDatabase, }; use itertools::Itertools; use stdx::trim_indent; use test_fixture::WithFixture; use test_utils::{MiniCore, assert_eq_text, extract_annotations}; -use crate::{DiagnosticsConfig, ExprFillDefaultMode, Severity}; +use crate::{DiagnosticsConfig, Severity}; /// Takes a multi-file input fixture with annotated cursor positions, /// and checks that: @@ -160,55 +162,6 @@ pub(crate) fn check_has_fix( assert!(fix.is_some(), "no diagnostic with desired fix"); } -#[track_caller] -pub(crate) fn check_has_single_fix( - #[rust_analyzer::rust_fixture] ra_fixture_before: &str, - #[rust_analyzer::rust_fixture] ra_fixture_after: &str, -) { - let after = trim_indent(ra_fixture_after); - - let (db, file_position) = RootDatabase::with_position(ra_fixture_before); - let mut conf = DiagnosticsConfig::test_sample(); - conf.expr_fill_default = ExprFillDefaultMode::Default; - let mut n_fixes = 0; - let fix = super::full_diagnostics( - &db, - &conf, - &AssistResolveStrategy::All, - file_position.file_id.file_id(&db), - ) - .into_iter() - .find(|d| { - d.fixes - .as_ref() - .and_then(|fixes| { - n_fixes += fixes.len(); - fixes.iter().find(|fix| { - if !fix.target.contains_inclusive(file_position.offset) { - return false; - } - let actual = { - let source_change = fix.source_change.as_ref().unwrap(); - let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).text(&db).to_string(); - - for (edit, snippet_edit) in source_change.source_file_edits.values() { - edit.apply(&mut actual); - if let Some(snippet_edit) = snippet_edit { - snippet_edit.apply(&mut actual); - } - } - actual - }; - after == actual - }) - }) - .is_some() - }); - assert!(fix.is_some(), "no diagnostic with desired fix"); - assert!(n_fixes == 1, "Too many fixes suggested"); -} - /// Checks that there's a diagnostic *without* fix at `$0`. pub(crate) fn check_no_fix(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let (db, file_position) = RootDatabase::with_position(ra_fixture); diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index ebbd68bcdf74..f0247f32d7ec 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -599,7 +599,7 @@ fn filename_and_frag_for_def( Some(name) => { match m.attrs(db).by_key(sym::doc).find_string_value_in_tt(sym::keyword) { Some(kw) => { - format!("keyword.{}.html", kw) + format!("keyword.{kw}.html") } None => format!("{}/index.html", name.as_str()), } diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index a13be6c4927f..e7f5fcbf69f3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -123,9 +123,9 @@ pub use ide_completion::{ CallableSnippets, CompletionConfig, CompletionFieldsToResolve, CompletionItem, CompletionItemKind, CompletionItemRefMode, CompletionRelevance, Snippet, SnippetScope, }; -pub use ide_db::text_edit::{Indel, TextEdit}; pub use ide_db::{ FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind, + assists::ExprFillDefaultMode, base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId}, documentation::Documentation, label::Label, @@ -134,8 +134,9 @@ pub use ide_db::{ search::{ReferenceCategory, SearchScope}, source_change::{FileSystemEdit, SnippetEdit, SourceChange}, symbol_index::Query, + text_edit::{Indel, TextEdit}, }; -pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode}; +pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig}; pub use ide_ssr::SsrError; pub use span::Edition; pub use syntax::{TextRange, TextSize}; diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 4a06cd919fc3..795c1f2ca3c0 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -451,7 +451,7 @@ mod tests { assert_eq!(x.len(), 1); match x.into_iter().next().unwrap() { MonikerResult::Local { enclosing_moniker } => { - panic!("Unexpected local enclosed in {:?}", enclosing_moniker); + panic!("Unexpected local enclosed in {enclosing_moniker:?}"); } MonikerResult::Moniker(x) => { assert_eq!(identifier, x.identifier.to_string()); diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index 55a0db2d8204..cfcd76d2aa3b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -51,8 +51,8 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { buf, "Crate: {}\n", match display_name { - Some(it) => format!("{it}({:?})", crate_id), - None => format!("{:?}", crate_id), + Some(it) => format!("{it}({crate_id:?})"), + None => format!("{crate_id:?}"), } ); format_to!(buf, " Root module file id: {}\n", root_file_id.index()); diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs index 4696fef3209a..7985279679c4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs @@ -80,7 +80,7 @@ impl<'a> dot::Labeller<'a, Crate, Edge<'a>> for DotCrateGraph<'_> { fn node_id(&'a self, n: &Crate) -> Id<'a> { let id = n.as_id().as_u32(); - Id::new(format!("_{:?}", id)).unwrap() + Id::new(format!("_{id:?}")).unwrap() } fn node_shape(&'a self, _node: &Crate) -> Option> { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs index 07a10aaae578..97c0c4bda7df 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs @@ -12,5 +12,5 @@ fn main() { let version_string = std::str::from_utf8(&output.stdout[..]) .expect("rustc --version output must be UTF-8") .trim(); - println!("cargo::rustc-env=RUSTC_VERSION={}", version_string); + println!("cargo::rustc-env=RUSTC_VERSION={version_string}"); } diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs index 5cf9be36f70c..0bb86467c78b 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs @@ -40,7 +40,7 @@ impl LoggerDb { /// it is meant to be run from outside any tracked functions. pub(crate) fn assert_logs(&self, expected: expect_test::Expect) { let logs = std::mem::take(&mut *self.logger.logs.lock().unwrap()); - expected.assert_eq(&format!("{:#?}", logs)); + expected.assert_eq(&format!("{logs:#?}")); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index a62005e3c085..c50df4b6d45e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -175,7 +175,7 @@ impl flags::AnalysisStats { UsizeWithUnderscore(dep_loc), UsizeWithUnderscore(dep_item_trees), ); - eprintln!(" dependency item stats: {}", dep_item_stats); + eprintln!(" dependency item stats: {dep_item_stats}"); // FIXME(salsa-transition): bring back stats for ParseQuery (file size) // and ParseMacroExpansionQuery (macro expansion "file") size whenever we implement @@ -295,7 +295,7 @@ impl flags::AnalysisStats { UsizeWithUnderscore(workspace_loc), UsizeWithUnderscore(workspace_item_trees), ); - eprintln!(" usages: {}", workspace_item_stats); + eprintln!(" usages: {workspace_item_stats}"); eprintln!(" Dependencies:"); eprintln!( @@ -303,7 +303,7 @@ impl flags::AnalysisStats { UsizeWithUnderscore(dep_loc), UsizeWithUnderscore(dep_item_trees), ); - eprintln!(" declarations: {}", dep_item_stats); + eprintln!(" declarations: {dep_item_stats}"); let crate_def_map_time = crate_def_map_sw.elapsed(); eprintln!("{:<20} {}", "Item Collection:", crate_def_map_time); @@ -1294,7 +1294,7 @@ impl fmt::Display for UsizeWithUnderscore { let num_str = self.0.to_string(); if num_str.len() <= 3 { - return write!(f, "{}", num_str); + return write!(f, "{num_str}"); } let mut result = String::new(); @@ -1307,7 +1307,7 @@ impl fmt::Display for UsizeWithUnderscore { } let result = result.chars().rev().collect::(); - write!(f, "{}", result) + write!(f, "{result}") } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs index 2062294f807c..d258c5d8191f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs @@ -265,10 +265,10 @@ impl flags::Scip { }; if !duplicate_symbol_errors.is_empty() { - eprintln!("{}", DUPLICATE_SYMBOLS_MESSAGE); + eprintln!("{DUPLICATE_SYMBOLS_MESSAGE}"); for (source_location, symbol) in duplicate_symbol_errors { - eprintln!("{}", source_location); - eprintln!(" Duplicate symbol: {}", symbol); + eprintln!("{source_location}"); + eprintln!(" Duplicate symbol: {symbol}"); eprintln!(); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index dd827949a9c2..9acbcc08a9dd 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -9,13 +9,14 @@ use cfg::{CfgAtom, CfgDiff}; use hir::Symbol; use ide::{ AssistConfig, CallHierarchyConfig, CallableSnippets, CompletionConfig, - CompletionFieldsToResolve, DiagnosticsConfig, ExprFillDefaultMode, GenericParameterHints, - HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, - InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, - Snippet, SnippetScope, SourceRootId, + CompletionFieldsToResolve, DiagnosticsConfig, GenericParameterHints, HighlightConfig, + HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, InlayHintsConfig, + JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope, + SourceRootId, }; use ide_db::{ SnippetCap, + assists::ExprFillDefaultMode, imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, }; use itertools::{Either, Itertools}; @@ -1493,6 +1494,11 @@ impl Config { term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64, term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(), code_action_grouping: self.code_action_group(), + expr_fill_default: match self.assist_expressionFillDefault(source_root) { + ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo, + ExprFillDefaultDef::Default => ExprFillDefaultMode::Default, + ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore, + }, } } @@ -1577,6 +1583,7 @@ impl Config { expr_fill_default: match self.assist_expressionFillDefault(source_root) { ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo, ExprFillDefaultDef::Default => ExprFillDefaultMode::Default, + ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore, }, snippet_cap: self.snippet_cap(), insert_use: self.insert_use_config(source_root), @@ -2527,6 +2534,7 @@ where enum ExprFillDefaultDef { Todo, Default, + Underscore, } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index d608a35effa1..9fe08c590461 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -69,6 +69,9 @@ pub mod ext { pub fn expr_todo() -> ast::Expr { expr_from_text("todo!()") } + pub fn expr_underscore() -> ast::Expr { + expr_from_text("_") + } pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr { expr_from_text(&format!("{ty}::default()")) } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 36ccb67f3b8d..1dbc07c0929c 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -728,9 +728,9 @@ fn print_debug_subtree( }; write!(f, "{align}SUBTREE {delim} ",)?; - write!(f, "{:#?}", open)?; + write!(f, "{open:#?}")?; write!(f, " ")?; - write!(f, "{:#?}", close)?; + write!(f, "{close:#?}")?; for child in iter { writeln!(f)?; print_debug_token(f, level + 1, child)?; @@ -855,7 +855,7 @@ impl fmt::Display for Literal { } }?; if let Some(suffix) = &self.suffix { - write!(f, "{}", suffix)?; + write!(f, "{suffix}")?; } Ok(()) } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 82df78c1a898..4b9c6edbe308 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -414,7 +414,7 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String { .map(|kind| to_pascal_case(kind)) .filter(|name| !defined_nodes.iter().any(|&it| it == name)) { - eprintln!("Warning: node {} not defined in AST source", node); + eprintln!("Warning: node {node} not defined in AST source"); drop(node); } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs index f3b786b9d867..ae53771fe8e5 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs @@ -159,7 +159,7 @@ fn collect_tests(s: &str) -> Vec { (name.to_owned(), Some(edition.to_owned())) } [name] => (name.to_owned(), None), - _ => panic!("invalid test name: {:?}", name), + _ => panic!("invalid test name: {name:?}"), }; let text: String = edition .as_ref() @@ -212,7 +212,7 @@ fn existing_tests(dir: &Path, ok: TestKind) -> Result Date: Thu, 27 Mar 2025 14:20:25 +0100 Subject: [PATCH 023/262] std: get rid of `sys_common::process` Move the public `CommandEnvs` into the `process` module (and make it a wrapper type for an internal iterator type) and everything else into `sys::process` as per #117276. --- library/std/src/process.rs | 48 ++++++- .../process.rs => sys/process/env.rs} | 48 +------ library/std/src/sys/process/mod.rs | 59 ++++++++ library/std/src/sys/process/uefi.rs | 128 +++++++++--------- library/std/src/sys/process/unix/common.rs | 2 +- library/std/src/sys/process/unix/fuchsia.rs | 5 - library/std/src/sys/process/unix/unix.rs | 5 - .../std/src/sys/process/unix/unsupported.rs | 8 +- library/std/src/sys/process/unix/vxworks.rs | 5 - library/std/src/sys/process/unsupported.rs | 8 +- library/std/src/sys/process/windows.rs | 7 +- library/std/src/sys_common/mod.rs | 1 - 12 files changed, 182 insertions(+), 142 deletions(-) rename library/std/src/{sys_common/process.rs => sys/process/env.rs} (67%) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 76ce7bce81b1..df6b9a6e563c 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -168,8 +168,6 @@ use crate::num::NonZero; use crate::path::Path; use crate::sys::pipe::{AnonPipe, read2}; use crate::sys::process as imp; -#[stable(feature = "command_access", since = "1.57.0")] -pub use crate::sys_common::process::CommandEnvs; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{fmt, fs, str}; @@ -1073,7 +1071,7 @@ impl Command { /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn output(&mut self) -> io::Result { - let (status, stdout, stderr) = self.inner.output()?; + let (status, stdout, stderr) = imp::output(&mut self.inner)?; Ok(Output { status: ExitStatus(status), stdout, stderr }) } @@ -1174,7 +1172,7 @@ impl Command { /// ``` #[stable(feature = "command_access", since = "1.57.0")] pub fn get_envs(&self) -> CommandEnvs<'_> { - self.inner.get_envs() + CommandEnvs { iter: self.inner.get_envs() } } /// Returns the working directory for the child process. @@ -1264,6 +1262,48 @@ impl<'a> ExactSizeIterator for CommandArgs<'a> { } } +/// An iterator over the command environment variables. +/// +/// This struct is created by +/// [`Command::get_envs`][crate::process::Command::get_envs]. See its +/// documentation for more. +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "command_access", since = "1.57.0")] +pub struct CommandEnvs<'a> { + iter: imp::CommandEnvs<'a>, +} + +#[stable(feature = "command_access", since = "1.57.0")] +impl<'a> Iterator for CommandEnvs<'a> { + type Item = (&'a OsStr, Option<&'a OsStr>); + + fn next(&mut self) -> Option { + self.iter.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +#[stable(feature = "command_access", since = "1.57.0")] +impl<'a> ExactSizeIterator for CommandEnvs<'a> { + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +#[stable(feature = "command_access", since = "1.57.0")] +impl<'a> fmt::Debug for CommandEnvs<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.iter.fmt(f) + } +} + /// The output of a finished process. /// /// This is returned in a Result by either the [`output`] method of a diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys/process/env.rs similarity index 67% rename from library/std/src/sys_common/process.rs rename to library/std/src/sys/process/env.rs index 9f61d69d8587..e08b476540ef 100644 --- a/library/std/src/sys_common/process.rs +++ b/library/std/src/sys/process/env.rs @@ -1,13 +1,9 @@ -#![allow(dead_code)] -#![unstable(feature = "process_internals", issue = "none")] - use crate::collections::BTreeMap; use crate::ffi::{OsStr, OsString}; -use crate::sys::pipe::read2; -use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes}; -use crate::{env, fmt, io}; +use crate::sys::process::EnvKey; +use crate::{env, fmt}; -// Stores a set of changes to an environment +/// Stores a set of changes to an environment #[derive(Clone, Default)] pub struct CommandEnv { clear: bool, @@ -92,30 +88,23 @@ impl CommandEnv { } } -/// An iterator over the command environment variables. -/// -/// This struct is created by -/// [`Command::get_envs`][crate::process::Command::get_envs]. See its -/// documentation for more. -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "command_access", since = "1.57.0")] #[derive(Debug)] pub struct CommandEnvs<'a> { iter: crate::collections::btree_map::Iter<'a, EnvKey, Option>, } -#[stable(feature = "command_access", since = "1.57.0")] impl<'a> Iterator for CommandEnvs<'a> { type Item = (&'a OsStr, Option<&'a OsStr>); + fn next(&mut self) -> Option { self.iter.next().map(|(key, value)| (key.as_ref(), value.as_deref())) } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } -#[stable(feature = "command_access", since = "1.57.0")] impl<'a> ExactSizeIterator for CommandEnvs<'a> { fn len(&self) -> usize { self.iter.len() @@ -124,30 +113,3 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> { self.iter.is_empty() } } - -pub fn wait_with_output( - mut process: Process, - mut pipes: StdioPipes, -) -> io::Result<(ExitStatus, Vec, Vec)> { - drop(pipes.stdin.take()); - - let (mut stdout, mut stderr) = (Vec::new(), Vec::new()); - match (pipes.stdout.take(), pipes.stderr.take()) { - (None, None) => {} - (Some(out), None) => { - let res = out.read_to_end(&mut stdout); - res.unwrap(); - } - (None, Some(err)) => { - let res = err.read_to_end(&mut stderr); - res.unwrap(); - } - (Some(out), Some(err)) => { - let res = read2(out, &mut stdout, err, &mut stderr); - res.unwrap(); - } - } - - let status = process.wait()?; - Ok((status, stdout, stderr)) -} diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs index 92cfac7f47cf..91c7005a3285 100644 --- a/library/std/src/sys/process/mod.rs +++ b/library/std/src/sys/process/mod.rs @@ -14,6 +14,65 @@ cfg_if::cfg_if! { } } +// This module is shared by all platforms, but nearly all platforms except for +// the "normal" UNIX ones leave some of this code unused. +#[cfg_attr(not(target_os = "linux"), allow(dead_code))] +mod env; + +pub use env::CommandEnvs; pub use imp::{ Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes, }; + +#[cfg(any( + all( + target_family = "unix", + not(any( + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "nuttx" + )) + ), + target_os = "windows", +))] +pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec, Vec)> { + use crate::sys::pipe::read2; + + let (mut process, mut pipes) = cmd.spawn(Stdio::MakePipe, false)?; + + drop(pipes.stdin.take()); + let (mut stdout, mut stderr) = (Vec::new(), Vec::new()); + match (pipes.stdout.take(), pipes.stderr.take()) { + (None, None) => {} + (Some(out), None) => { + let res = out.read_to_end(&mut stdout); + res.unwrap(); + } + (None, Some(err)) => { + let res = err.read_to_end(&mut stderr); + res.unwrap(); + } + (Some(out), Some(err)) => { + let res = read2(out, &mut stdout, err, &mut stderr); + res.unwrap(); + } + } + + let status = process.wait()?; + Ok((status, stdout, stderr)) +} + +#[cfg(not(any( + all( + target_family = "unix", + not(any( + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "nuttx" + )) + ), + target_os = "windows", +)))] +pub use imp::output; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 5f922292d054..4864c5869881 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -1,5 +1,6 @@ use r_efi::protocols::{simple_text_input, simple_text_output}; +use super::env::{CommandEnv, CommandEnvs}; use crate::collections::BTreeMap; pub use crate::ffi::OsString as EnvKey; use crate::ffi::{OsStr, OsString}; @@ -10,7 +11,6 @@ use crate::sys::pal::helpers; use crate::sys::pal::os::error_string; use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; -use crate::sys_common::process::{CommandEnv, CommandEnvs}; use crate::{fmt, io}; //////////////////////////////////////////////////////////////////////////////// @@ -139,72 +139,72 @@ impl Command { Stdio::MakePipe => unsupported(), } } +} - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?; +pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec, Vec)> { + let mut cmd = uefi_command_internal::Image::load_image(&command.prog)?; - // UEFI adds the bin name by default - if !self.args.is_empty() { - let args = uefi_command_internal::create_args(&self.prog, &self.args); - cmd.set_args(args); - } - - // Setup Stdout - let stdout = self.stdout.unwrap_or(Stdio::MakePipe); - let stdout = Self::create_pipe(stdout)?; - if let Some(con) = stdout { - cmd.stdout_init(con) - } else { - cmd.stdout_inherit() - }; - - // Setup Stderr - let stderr = self.stderr.unwrap_or(Stdio::MakePipe); - let stderr = Self::create_pipe(stderr)?; - if let Some(con) = stderr { - cmd.stderr_init(con) - } else { - cmd.stderr_inherit() - }; - - // Setup Stdin - let stdin = self.stdin.unwrap_or(Stdio::Null); - let stdin = Self::create_stdin(stdin)?; - if let Some(con) = stdin { - cmd.stdin_init(con) - } else { - cmd.stdin_inherit() - }; - - let env = env_changes(&self.env); - - // Set any new vars - if let Some(e) = &env { - for (k, (_, v)) in e { - match v { - Some(v) => unsafe { crate::env::set_var(k, v) }, - None => unsafe { crate::env::remove_var(k) }, - } - } - } - - let stat = cmd.start_image()?; - - // Rollback any env changes - if let Some(e) = env { - for (k, (v, _)) in e { - match v { - Some(v) => unsafe { crate::env::set_var(k, v) }, - None => unsafe { crate::env::remove_var(k) }, - } - } - } - - let stdout = cmd.stdout()?; - let stderr = cmd.stderr()?; - - Ok((ExitStatus(stat), stdout, stderr)) + // UEFI adds the bin name by default + if !command.args.is_empty() { + let args = uefi_command_internal::create_args(&command.prog, &command.args); + cmd.set_args(args); } + + // Setup Stdout + let stdout = command.stdout.unwrap_or(Stdio::MakePipe); + let stdout = Command::create_pipe(stdout)?; + if let Some(con) = stdout { + cmd.stdout_init(con) + } else { + cmd.stdout_inherit() + }; + + // Setup Stderr + let stderr = command.stderr.unwrap_or(Stdio::MakePipe); + let stderr = Command::create_pipe(stderr)?; + if let Some(con) = stderr { + cmd.stderr_init(con) + } else { + cmd.stderr_inherit() + }; + + // Setup Stdin + let stdin = command.stdin.unwrap_or(Stdio::Null); + let stdin = Command::create_stdin(stdin)?; + if let Some(con) = stdin { + cmd.stdin_init(con) + } else { + cmd.stdin_inherit() + }; + + let env = env_changes(&command.env); + + // Set any new vars + if let Some(e) = &env { + for (k, (_, v)) in e { + match v { + Some(v) => unsafe { crate::env::set_var(k, v) }, + None => unsafe { crate::env::remove_var(k) }, + } + } + } + + let stat = cmd.start_image()?; + + // Rollback any env changes + if let Some(e) = env { + for (k, (v, _)) in e { + match v { + Some(v) => unsafe { crate::env::set_var(k, v) }, + None => unsafe { crate::env::remove_var(k) }, + } + } + } + + let stdout = cmd.stdout()?; + let stderr = cmd.stderr()?; + + Ok((ExitStatus(stat), stdout, stderr)) } impl From for Stdio { diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index 8bc17f314911..a9c2510e6d45 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -12,7 +12,7 @@ use crate::sys::fs::File; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; use crate::sys::pipe::{self, AnonPipe}; -use crate::sys_common::process::{CommandEnv, CommandEnvs}; +use crate::sys::process::env::{CommandEnv, CommandEnvs}; use crate::sys_common::{FromInner, IntoInner}; use crate::{fmt, io, ptr}; diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs index 0de32ecffd4b..fbe06c4799be 100644 --- a/library/std/src/sys/process/unix/fuchsia.rs +++ b/library/std/src/sys/process/unix/fuchsia.rs @@ -31,11 +31,6 @@ impl Command { Ok((Process { handle: Handle::new(process_handle) }, ours)) } - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; - crate::sys_common::process::wait_with_output(proc, pipes) - } - pub fn exec(&mut self, default: Stdio) -> io::Error { if self.saw_nul() { return io::const_error!( diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index ae1c9558281e..1b3bd2de265d 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -162,11 +162,6 @@ impl Command { } } - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; - crate::sys_common::process::wait_with_output(proc, pipes) - } - // WatchOS and TVOS headers mark the `fork`/`exec*` functions with // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the // `posix_spawn*` functions should be used instead. It isn't entirely clear diff --git a/library/std/src/sys/process/unix/unsupported.rs b/library/std/src/sys/process/unix/unsupported.rs index 78d270923cfa..e86561a5c5c4 100644 --- a/library/std/src/sys/process/unix/unsupported.rs +++ b/library/std/src/sys/process/unix/unsupported.rs @@ -18,15 +18,15 @@ impl Command { unsupported() } - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - unsupported() - } - pub fn exec(&mut self, _default: Stdio) -> io::Error { unsupported_err() } } +pub fn output(_: &mut Command) -> io::Result<(ExitStatus, Vec, Vec)> { + unsupported() +} + //////////////////////////////////////////////////////////////////////////////// // Processes //////////////////////////////////////////////////////////////////////////////// diff --git a/library/std/src/sys/process/unix/vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs index b92446f0cf67..fab3b36ebf3f 100644 --- a/library/std/src/sys/process/unix/vxworks.rs +++ b/library/std/src/sys/process/unix/vxworks.rs @@ -112,11 +112,6 @@ impl Command { } } - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; - crate::sys_common::process::wait_with_output(proc, pipes) - } - pub fn exec(&mut self, default: Stdio) -> io::Error { let ret = Command::spawn(self, default, false); match ret { diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs index fee81744f09e..469922c78aca 100644 --- a/library/std/src/sys/process/unsupported.rs +++ b/library/std/src/sys/process/unsupported.rs @@ -1,3 +1,4 @@ +use super::env::{CommandEnv, CommandEnvs}; pub use crate::ffi::OsString as EnvKey; use crate::ffi::{OsStr, OsString}; use crate::num::NonZero; @@ -5,7 +6,6 @@ use crate::path::Path; use crate::sys::fs::File; use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; -use crate::sys_common::process::{CommandEnv, CommandEnvs}; use crate::{fmt, io}; //////////////////////////////////////////////////////////////////////////////// @@ -104,10 +104,10 @@ impl Command { ) -> io::Result<(Process, StdioPipes)> { unsupported() } +} - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - unsupported() - } +pub fn output(_cmd: &mut Command) -> io::Result<(ExitStatus, Vec, Vec)> { + unsupported() } impl From for Stdio { diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs index 4cfdf908c58d..4acd753eec91 100644 --- a/library/std/src/sys/process/windows.rs +++ b/library/std/src/sys/process/windows.rs @@ -5,6 +5,7 @@ mod tests; use core::ffi::c_void; +use super::env::{CommandEnv, CommandEnvs}; use crate::collections::BTreeMap; use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX}; use crate::ffi::{OsStr, OsString}; @@ -24,7 +25,6 @@ use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::pipe::{self, AnonPipe}; use crate::sys::{cvt, path, stdio}; use crate::sys_common::IntoInner; -use crate::sys_common::process::{CommandEnv, CommandEnvs}; use crate::{cmp, env, fmt, ptr}; //////////////////////////////////////////////////////////////////////////////// @@ -389,11 +389,6 @@ impl Command { )) } } - - pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { - let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; - crate::sys_common::process::wait_with_output(proc, pipes) - } } impl fmt::Debug for Command { diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 2a5de7f66661..b7f4656fa370 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -20,7 +20,6 @@ #[cfg(test)] mod tests; -pub mod process; pub mod wstr; pub mod wtf8; From 99f00927cc1de78b812ddc422b2e425b1fdbf998 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 28 Apr 2025 11:55:26 +0200 Subject: [PATCH 024/262] fix: Address minor FIXME --- .../crates/hir-def/src/item_scope.rs | 19 ++++++++----------- .../hir-def/src/nameres/path_resolution.rs | 5 ++--- .../crates/hir-def/src/per_ns.rs | 12 +++++------- .../crates/hir-def/src/resolver.rs | 2 +- .../rust-analyzer/crates/hir/src/symbols.rs | 5 +++-- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index bece940950d8..5362c0588dbe 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -167,7 +167,7 @@ pub struct ItemScope { // the resolutions of the imports of this scope use_imports_types: FxHashMap, use_imports_values: FxHashMap, - use_imports_macros: FxHashMap, + use_imports_macros: FxHashMap, use_decls: Vec, extern_crate_decls: Vec, @@ -242,7 +242,7 @@ impl ItemScope { self.types.iter().map(|(n, &i)| (n, i)) } - pub fn macros(&self) -> impl Iterator)> + '_ { + pub fn macros(&self) -> impl Iterator)> + '_ { self.macros.iter().map(|(n, &i)| (n, i)) } @@ -250,9 +250,9 @@ impl ItemScope { self.use_imports_types .keys() .copied() + .chain(self.use_imports_macros.keys().copied()) .filter_map(ImportOrExternCrate::import_or_glob) .chain(self.use_imports_values.keys().copied()) - .chain(self.use_imports_macros.keys().copied()) .filter_map(ImportOrGlob::into_import) .sorted() .dedup() @@ -263,7 +263,7 @@ impl ItemScope { let mut def_map; let mut scope = self; - while let Some(&m) = scope.use_imports_macros.get(&ImportOrGlob::Import(import)) { + while let Some(&m) = scope.use_imports_macros.get(&ImportOrExternCrate::Import(import)) { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; @@ -682,7 +682,6 @@ impl ItemScope { } _ => _ = glob_imports.macros.remove(&lookup), } - let import = import.and_then(ImportOrExternCrate::import_or_glob); let prev = std::mem::replace(&mut fld.import, import); if let Some(import) = import { self.use_imports_macros.insert( @@ -698,7 +697,6 @@ impl ItemScope { { if glob_imports.macros.remove(&lookup) { cov_mark::hit!(import_shadowed); - let import = import.and_then(ImportOrExternCrate::import_or_glob); let prev = std::mem::replace(&mut fld.import, import); if let Some(import) = import { self.use_imports_macros.insert( @@ -783,8 +781,9 @@ impl ItemScope { if let Some(Item { import, .. }) = def.macros { buf.push_str(" m"); match import { - Some(ImportOrGlob::Import(_)) => buf.push('i'), - Some(ImportOrGlob::Glob(_)) => buf.push('g'), + Some(ImportOrExternCrate::Import(_)) => buf.push('i'), + Some(ImportOrExternCrate::Glob(_)) => buf.push('g'), + Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'), None => (), } } @@ -893,9 +892,7 @@ impl PerNs { ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import), ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import), ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import), - ModuleDefId::MacroId(mac) => { - PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::import_or_glob)) - } + ModuleDefId::MacroId(mac) => PerNs::macros(mac, v, import), } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index f8b2c73a8f68..a49155d878ca 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -673,12 +673,11 @@ impl DefMap { } fn resolve_in_macro_use_prelude(&self, name: &Name) -> PerNs { - self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| { + self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| { PerNs::macros( it, Visibility::Public, - // FIXME? - None, // extern_crate.map(ImportOrExternCrate::ExternCrate), + extern_crate.map(ImportOrExternCrate::ExternCrate), ) }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs index 1f7dd6f0c407..8721cd65dbac 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs @@ -37,7 +37,8 @@ pub struct Item { pub type TypesItem = Item; pub type ValuesItem = Item; -pub type MacrosItem = Item; +// May be Externcrate for `[macro_use]`'d macros +pub type MacrosItem = Item; #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] pub struct PerNs { @@ -84,7 +85,7 @@ impl PerNs { } } - pub fn macros(def: MacroId, vis: Visibility, import: Option) -> PerNs { + pub fn macros(def: MacroId, vis: Visibility, import: Option) -> PerNs { PerNs { types: None, values: None, macros: Some(Item { def, vis, import }) } } @@ -116,7 +117,7 @@ impl PerNs { self.macros.map(|it| it.def) } - pub fn take_macros_import(self) -> Option<(MacroId, Option)> { + pub fn take_macros_import(self) -> Option<(MacroId, Option)> { self.macros.map(|it| (it.def, it.import)) } @@ -158,9 +159,6 @@ impl PerNs { self.values .map(|it| (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::from))), ) - .chain( - self.macros - .map(|it| (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::from))), - ) + .chain(self.macros.map(|it| (ItemInNs::Macros(it.def), it.import))) } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 9b9335f19116..552b4961f5e2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -493,7 +493,7 @@ impl Resolver { db: &dyn DefDatabase, path: &ModPath, expected_macro_kind: Option, - ) -> Option<(MacroId, Option)> { + ) -> Option<(MacroId, Option)> { let (item_map, item_local_map, module) = self.item_scope_(); item_map .resolve_path( diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 41064d047a5a..3d944afb8b30 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -263,8 +263,9 @@ impl<'a> SymbolCollector<'a> { for (name, Item { def, vis, import }) in scope.macros() { if let Some(i) = import { match i { - ImportOrGlob::Import(i) => push_import(self, i, name, def.into(), vis), - ImportOrGlob::Glob(_) => (), + ImportOrExternCrate::Import(i) => push_import(self, i, name, def.into(), vis), + ImportOrExternCrate::Glob(_) => (), + ImportOrExternCrate::ExternCrate(_) => (), } continue; } From 2231efa27d12428f76e12990bb00948a26506947 Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Tue, 8 Apr 2025 14:18:09 +0530 Subject: [PATCH 025/262] refactor: migrate `let_else_to_match` to editor Signed-off-by: Prajwal S N --- .../src/handlers/add_missing_match_arms.rs | 4 +- .../src/handlers/convert_let_else_to_match.rs | 299 ++++++++++-------- .../handlers/destructure_struct_binding.rs | 4 +- .../src/handlers/expand_rest_pattern.rs | 7 +- .../src/handlers/unmerge_match_arm.rs | 10 +- .../src/handlers/missing_fields.rs | 11 +- .../crates/syntax/src/ast/make.rs | 32 +- .../src/ast/syntax_factory/constructors.rs | 110 ++++++- 8 files changed, 335 insertions(+), 142 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 05d21cb97933..858d4369914a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -493,8 +493,8 @@ fn build_pat( hir::StructKind::Record => { let fields = fields .into_iter() - .map(|f| make.name_ref(f.name(db).as_str())) - .map(|name_ref| make.record_pat_field_shorthand(name_ref)); + .map(|f| make.ident_pat(false, false, make.name(f.name(db).as_str()))) + .map(|ident| make.record_pat_field_shorthand(ident.into())); let fields = make.record_pat_field_list(fields, None); make.record_pat_with_fields(path, fields).into() } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs index df92b07cba7c..ebfed9f9ca99 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs @@ -1,8 +1,9 @@ -use hir::Semantics; -use ide_db::RootDatabase; use syntax::T; use syntax::ast::RangeItem; -use syntax::ast::{AstNode, HasName, LetStmt, Name, Pat, edit::AstNodeEdit}; +use syntax::ast::edit::IndentLevel; +use syntax::ast::edit_in_place::Indent; +use syntax::ast::syntax_factory::SyntaxFactory; +use syntax::ast::{self, AstNode, HasName, LetStmt, Pat}; use crate::{AssistContext, AssistId, Assists}; @@ -25,155 +26,205 @@ use crate::{AssistContext, AssistId, Assists}; // } // ``` pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - // should focus on else token to trigger + // Should focus on the `else` token to trigger let let_stmt = ctx .find_token_syntax_at_offset(T![else]) .and_then(|it| it.parent()?.parent()) .or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?; let let_stmt = LetStmt::cast(let_stmt)?; - let let_else_block = let_stmt.let_else()?.block_expr()?; - let let_init = let_stmt.initializer()?; + let else_block = let_stmt.let_else()?.block_expr()?; + let else_expr = if else_block.statements().next().is_none() { + else_block.tail_expr()? + } else { + else_block.into() + }; + let init = let_stmt.initializer()?; + // Ignore let stmt with type annotation if let_stmt.ty().is_some() { - // don't support let with type annotation return None; } let pat = let_stmt.pat()?; - let mut binders = Vec::new(); - binders_in_pat(&mut binders, &pat, &ctx.sema)?; - let target = let_stmt.syntax().text_range(); + let make = SyntaxFactory::with_mappings(); + let mut idents = Vec::default(); + let pat_without_mut = remove_mut_and_collect_idents(&make, &pat, &mut idents)?; + let bindings = idents + .into_iter() + .filter_map(|ref pat| { + // Identifiers which resolve to constants are not bindings + if ctx.sema.resolve_bind_pat_to_const(pat).is_none() { + Some((pat.name()?, pat.ref_token().is_none() && pat.mut_token().is_some())) + } else { + None + } + }) + .collect::>(); + acc.add( AssistId::refactor_rewrite("convert_let_else_to_match"), - "Convert let-else to let and match", - target, - |edit| { - let indent_level = let_stmt.indent_level().0 as usize; - let indent = " ".repeat(indent_level); - let indent1 = " ".repeat(indent_level + 1); + if bindings.is_empty() { + "Convert let-else to match" + } else { + "Convert let-else to let and match" + }, + let_stmt.syntax().text_range(), + |builder| { + let mut editor = builder.make_editor(let_stmt.syntax()); - let binders_str = binders_to_str(&binders, false); - let binders_str_mut = binders_to_str(&binders, true); + let binding_paths = bindings + .iter() + .map(|(name, _)| make.expr_path(make.ident_path(&name.to_string()))) + .collect::>(); - let init_expr = let_init.syntax().text(); - let mut pat_no_mut = pat.syntax().text().to_string(); - // remove the mut from the pattern - for (b, ismut) in binders.iter() { - if *ismut { - pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string()); - } + let binding_arm = make.match_arm( + pat_without_mut, + None, + // There are three possible cases: + // + // - No bindings: `None => {}` + // - Single binding: `Some(it) => it` + // - Multiple bindings: `Foo::Bar { a, b, .. } => (a, b)` + match binding_paths.len() { + 0 => make.expr_empty_block().into(), + + 1 => binding_paths[0].clone(), + _ => make.expr_tuple(binding_paths).into(), + }, + ); + let else_arm = make.match_arm(make.wildcard_pat().into(), None, else_expr); + let match_ = make.expr_match(init, make.match_arm_list([binding_arm, else_arm])); + match_.reindent_to(IndentLevel::from_node(let_stmt.syntax())); + + if bindings.is_empty() { + editor.replace(let_stmt.syntax(), match_.syntax()); + } else { + let ident_pats = bindings + .into_iter() + .map(|(name, is_mut)| make.ident_pat(false, is_mut, name).into()) + .collect::>(); + let new_let_stmt = make.let_stmt( + if ident_pats.len() == 1 { + ident_pats[0].clone() + } else { + make.tuple_pat(ident_pats).into() + }, + None, + Some(match_.into()), + ); + editor.replace(let_stmt.syntax(), new_let_stmt.syntax()); } - let only_expr = let_else_block.statements().next().is_none(); - let branch2 = match &let_else_block.tail_expr() { - Some(tail) if only_expr => format!("{tail},"), - _ => let_else_block.syntax().text().to_string(), - }; - let replace = if binders.is_empty() { - format!( - "match {init_expr} {{ -{indent1}{pat_no_mut} => {binders_str} -{indent1}_ => {branch2} -{indent}}}" - ) - } else { - format!( - "let {binders_str_mut} = match {init_expr} {{ -{indent1}{pat_no_mut} => {binders_str}, -{indent1}_ => {branch2} -{indent}}};" - ) - }; - edit.replace(target, replace); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } -/// Gets a list of binders in a pattern, and whether they are mut. -fn binders_in_pat( - acc: &mut Vec<(Name, bool)>, - pat: &Pat, - sem: &Semantics<'_, RootDatabase>, -) -> Option<()> { - use Pat::*; - match pat { - IdentPat(p) => { - let ident = p.name()?; - let ismut = p.ref_token().is_none() && p.mut_token().is_some(); - // check for const reference - if sem.resolve_bind_pat_to_const(p).is_none() { - acc.push((ident, ismut)); - } +fn remove_mut_and_collect_idents( + make: &SyntaxFactory, + pat: &ast::Pat, + acc: &mut Vec, +) -> Option { + Some(match pat { + ast::Pat::IdentPat(p) => { + acc.push(p.clone()); + let non_mut_pat = make.ident_pat( + p.ref_token().is_some(), + p.ref_token().is_some() && p.mut_token().is_some(), + p.name()?, + ); if let Some(inner) = p.pat() { - binders_in_pat(acc, &inner, sem)?; + non_mut_pat.set_pat(remove_mut_and_collect_idents(make, &inner, acc)); } - Some(()) + non_mut_pat.into() } - BoxPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), - RestPat(_) | LiteralPat(_) | PathPat(_) | WildcardPat(_) | ConstBlockPat(_) => Some(()), - OrPat(p) => { - for p in p.pats() { - binders_in_pat(acc, &p, sem)?; - } - Some(()) + ast::Pat::BoxPat(p) => { + make.box_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into() } - ParenPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), - RangePat(p) => { - if let Some(st) = p.start() { - binders_in_pat(acc, &st, sem)? - } - if let Some(ed) = p.end() { - binders_in_pat(acc, &ed, sem)? - } - Some(()) + ast::Pat::OrPat(p) => make + .or_pat( + p.pats() + .map(|pat| remove_mut_and_collect_idents(make, &pat, acc)) + .collect::>>()?, + p.leading_pipe().is_some(), + ) + .into(), + ast::Pat::ParenPat(p) => { + make.paren_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into() } - RecordPat(p) => { - for f in p.record_pat_field_list()?.fields() { - let pat = f.pat()?; - binders_in_pat(acc, &pat, sem)?; + ast::Pat::RangePat(p) => make + .range_pat( + if let Some(start) = p.start() { + Some(remove_mut_and_collect_idents(make, &start, acc)?) + } else { + None + }, + if let Some(end) = p.end() { + Some(remove_mut_and_collect_idents(make, &end, acc)?) + } else { + None + }, + ) + .into(), + ast::Pat::RecordPat(p) => make + .record_pat_with_fields( + p.path()?, + make.record_pat_field_list( + p.record_pat_field_list()? + .fields() + .map(|field| { + remove_mut_and_collect_idents(make, &field.pat()?, acc).map(|pat| { + if let Some(name_ref) = field.name_ref() { + make.record_pat_field(name_ref, pat) + } else { + make.record_pat_field_shorthand(pat) + } + }) + }) + .collect::>>()?, + p.record_pat_field_list()?.rest_pat(), + ), + ) + .into(), + ast::Pat::RefPat(p) => { + let inner = p.pat()?; + if let ast::Pat::IdentPat(ident) = inner { + acc.push(ident); + p.clone_for_update().into() + } else { + make.ref_pat(remove_mut_and_collect_idents(make, &inner, acc)?).into() } - Some(()) - } - RefPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), - SlicePat(p) => { - for p in p.pats() { - binders_in_pat(acc, &p, sem)?; - } - Some(()) - } - TuplePat(p) => { - for p in p.fields() { - binders_in_pat(acc, &p, sem)?; - } - Some(()) - } - TupleStructPat(p) => { - for p in p.fields() { - binders_in_pat(acc, &p, sem)?; - } - Some(()) } + ast::Pat::SlicePat(p) => make + .slice_pat( + p.pats() + .map(|pat| remove_mut_and_collect_idents(make, &pat, acc)) + .collect::>>()?, + ) + .into(), + ast::Pat::TuplePat(p) => make + .tuple_pat( + p.fields() + .map(|field| remove_mut_and_collect_idents(make, &field, acc)) + .collect::>>()?, + ) + .into(), + ast::Pat::TupleStructPat(p) => make + .tuple_struct_pat( + p.path()?, + p.fields() + .map(|field| remove_mut_and_collect_idents(make, &field, acc)) + .collect::>>()?, + ) + .into(), + ast::Pat::RestPat(_) + | ast::Pat::LiteralPat(_) + | ast::Pat::PathPat(_) + | ast::Pat::WildcardPat(_) + | ast::Pat::ConstBlockPat(_) => pat.clone(), // don't support macro pat yet - MacroPat(_) => None, - } -} - -fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String { - let vars = binders - .iter() - .map( - |(ident, ismut)| { - if *ismut && addmut { format!("mut {ident}") } else { ident.to_string() } - }, - ) - .collect::>() - .join(", "); - if binders.is_empty() { - String::from("{}") - } else if binders.len() == 1 { - vars - } else { - format!("({vars})") - } + ast::Pat::MacroPat(_) => return None, + }) } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 800ef89ac6ed..b8c647ac8b71 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -196,7 +196,9 @@ fn destructure_pat( let fields = field_names.iter().map(|(old_name, new_name)| { // Use shorthand syntax if possible if old_name == new_name && !is_mut { - make.record_pat_field_shorthand(make.name_ref(old_name)) + make.record_pat_field_shorthand( + make.ident_pat(false, false, make.name(old_name)).into(), + ) } else { make.record_pat_field( make.name_ref(old_name), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index 4e487e216264..b71de5e00c6a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -56,7 +56,12 @@ fn expand_record_rest_pattern( let new_field_list = make.record_pat_field_list(old_field_list.fields(), None); for (f, _) in missing_fields.iter() { let field = make.record_pat_field_shorthand( - make.name_ref(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()), + make.ident_pat( + false, + false, + make.name(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()), + ) + .into(), ); new_field_list.add_field(field); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs index 31ff47a05492..5aedff5cc775 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs @@ -53,8 +53,14 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O |edit| { let pats_after = pipe_token .siblings_with_tokens(Direction::Next) - .filter_map(|it| ast::Pat::cast(it.into_node()?)); - let new_pat = make::or_pat(pats_after, or_pat.leading_pipe().is_some()); + .filter_map(|it| ast::Pat::cast(it.into_node()?)) + .collect::>(); + // It is guaranteed that `pats_after` has at least one element + let new_pat = if pats_after.len() == 1 { + pats_after[0].clone() + } else { + make::or_pat(pats_after, or_pat.leading_pipe().is_some()).into() + }; let new_match_arm = make::match_arm(new_pat, match_arm.guard(), match_arm_body).clone_for_update(); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index 9aea2b1056d2..a354d123f5ab 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -163,9 +163,14 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option ast::WildcardPat { } pub fn rest_pat() -> ast::RestPat { - ast_from_text("fn f(..)") + ast_from_text("fn f() { let ..; }") } pub fn literal_pat(lit: &str) -> ast::LiteralPat { @@ -788,8 +788,8 @@ pub fn record_pat_field(name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPat ast_from_text(&format!("fn f(S {{ {name_ref}: {pat} }}: ()))")) } -pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField { - ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))")) +pub fn record_pat_field_shorthand(pat: ast::Pat) -> ast::RecordPatField { + ast_from_text(&format!("fn f(S {{ {pat} }}: ()))")) } /// Returns a `IdentPat` if the path has just one segment, a `PathPat` otherwise. @@ -801,16 +801,38 @@ pub fn path_pat(path: ast::Path) -> ast::Pat { } /// Returns a `Pat` if the path has just one segment, an `OrPat` otherwise. -pub fn or_pat(pats: impl IntoIterator, leading_pipe: bool) -> ast::Pat { +/// +/// Invariant: `pats` must be length > 1. +pub fn or_pat(pats: impl IntoIterator, leading_pipe: bool) -> ast::OrPat { let leading_pipe = if leading_pipe { "| " } else { "" }; let pats = pats.into_iter().join(" | "); return from_text(&format!("{leading_pipe}{pats}")); - fn from_text(text: &str) -> ast::Pat { + fn from_text(text: &str) -> ast::OrPat { ast_from_text(&format!("fn f({text}: ())")) } } +pub fn box_pat(pat: ast::Pat) -> ast::BoxPat { + ast_from_text(&format!("fn f(box {pat}: ())")) +} + +pub fn paren_pat(pat: ast::Pat) -> ast::ParenPat { + ast_from_text(&format!("fn f(({pat}): ())")) +} + +pub fn range_pat(start: Option, end: Option) -> ast::RangePat { + ast_from_text(&format!( + "fn f({}..{}: ())", + start.map(|e| e.to_string()).unwrap_or_default(), + end.map(|e| e.to_string()).unwrap_or_default() + )) +} + +pub fn ref_pat(pat: ast::Pat) -> ast::RefPat { + ast_from_text(&format!("fn f(&{pat}: ())")) +} + pub fn match_arm(pat: ast::Pat, guard: Option, expr: ast::Expr) -> ast::MatchArm { return match guard { Some(guard) => from_text(&format!("{pat} {guard} => {expr}")), diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 1854000d3db2..3b205516c223 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -3,7 +3,7 @@ use crate::{ AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, ast::{ self, HasArgList, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, HasTypeBounds, - HasVisibility, make, + HasVisibility, RangeItem, make, }, syntax_editor::SyntaxMappingBuilder, }; @@ -254,12 +254,12 @@ impl SyntaxFactory { ast } - pub fn record_pat_field_shorthand(&self, name_ref: ast::NameRef) -> ast::RecordPatField { - let ast = make::record_pat_field_shorthand(name_ref.clone()).clone_for_update(); + pub fn record_pat_field_shorthand(&self, pat: ast::Pat) -> ast::RecordPatField { + let ast = make::record_pat_field_shorthand(pat.clone()).clone_for_update(); if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_node(name_ref.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); builder.finish(&mut mapping); } @@ -294,6 +294,76 @@ impl SyntaxFactory { make::rest_pat().clone_for_update() } + pub fn or_pat( + &self, + pats: impl IntoIterator, + leading_pipe: bool, + ) -> ast::OrPat { + let (pats, input) = iterator_input(pats); + let ast = make::or_pat(pats, leading_pipe).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.pats().map(|it| it.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + + pub fn box_pat(&self, pat: ast::Pat) -> ast::BoxPat { + let ast = make::box_pat(pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn paren_pat(&self, pat: ast::Pat) -> ast::ParenPat { + let ast = make::paren_pat(pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn range_pat(&self, start: Option, end: Option) -> ast::RangePat { + let ast = make::range_pat(start.clone(), end.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(start) = start { + builder.map_node(start.syntax().clone(), ast.start().unwrap().syntax().clone()); + } + if let Some(end) = end { + builder.map_node(end.syntax().clone(), ast.end().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn ref_pat(&self, pat: ast::Pat) -> ast::RefPat { + let ast = make::ref_pat(pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn block_expr( &self, statements: impl IntoIterator, @@ -673,6 +743,38 @@ impl SyntaxFactory { ast } + pub fn let_else_stmt( + &self, + pattern: ast::Pat, + ty: Option, + initializer: ast::Expr, + diverging: ast::BlockExpr, + ) -> ast::LetStmt { + let ast = make::let_else_stmt( + pattern.clone(), + ty.clone(), + initializer.clone(), + diverging.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pattern.syntax().clone(), ast.pat().unwrap().syntax().clone()); + if let Some(input) = ty { + builder.map_node(input.syntax().clone(), ast.ty().unwrap().syntax().clone()); + } + builder.map_node( + initializer.syntax().clone(), + ast.initializer().unwrap().syntax().clone(), + ); + builder.map_node(diverging.syntax().clone(), ast.let_else().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn type_arg(&self, ty: ast::Type) -> ast::TypeArg { let ast = make::type_arg(ty.clone()).clone_for_update(); From 1b3374fb820aea675770223bcd398550f42d9553 Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Fri, 28 Mar 2025 03:15:10 +0530 Subject: [PATCH 026/262] fix: migrate `unmerge_use` to syntax editor Also ensures that attributes on the use item are applied to the new use item when unmerging. Signed-off-by: Prajwal S N --- .../ide-assists/src/handlers/unmerge_use.rs | 59 ++++++++++++++----- .../src/ast/syntax_factory/constructors.rs | 14 +++++ .../crates/syntax/src/syntax_editor.rs | 1 + .../crates/syntax/src/syntax_editor/edits.rs | 50 +++++++++++++++- 4 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs index 805a7344494a..558e6e0697ea 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs @@ -1,7 +1,10 @@ use syntax::{ AstNode, SyntaxKind, - ast::{self, HasVisibility, edit_in_place::Removable, make}, - ted::{self, Position}, + ast::{ + self, HasAttrs, HasVisibility, edit::IndentLevel, edit_in_place::AttrsOwnerEdit, make, + syntax_factory::SyntaxFactory, + }, + syntax_editor::{Element, Position, Removable}, }; use crate::{ @@ -22,7 +25,7 @@ use crate::{ // use std::fmt::Display; // ``` pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let tree: ast::UseTree = ctx.find_node_at_offset::()?.clone_for_update(); + let tree = ctx.find_node_at_offset::()?; let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?; if tree_list.use_trees().count() < 2 { @@ -30,12 +33,9 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< return None; } - let use_: ast::Use = tree_list.syntax().ancestors().find_map(ast::Use::cast)?; + let use_ = tree_list.syntax().ancestors().find_map(ast::Use::cast)?; let path = resolve_full_path(&tree)?; - let old_parent_range = use_.syntax().parent()?.text_range(); - let new_parent = use_.syntax().parent()?; - // If possible, explain what is going to be done. let label = match tree.path().and_then(|path| path.first_segment()) { Some(name) => format!("Unmerge use of `{name}`"), @@ -44,16 +44,30 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< let target = tree.syntax().text_range(); acc.add(AssistId::refactor_rewrite("unmerge_use"), label, target, |builder| { - let new_use = make::use_( + let make = SyntaxFactory::with_mappings(); + let new_use = make.use_( use_.visibility(), - make::use_tree(path, tree.use_tree_list(), tree.rename(), tree.star_token().is_some()), - ) - .clone_for_update(); + make.use_tree(path, tree.use_tree_list(), tree.rename(), tree.star_token().is_some()), + ); + // Add any attributes that are present on the use tree + use_.attrs().for_each(|attr| { + new_use.add_attr(attr.clone_for_update()); + }); - tree.remove(); - ted::insert(Position::after(use_.syntax()), new_use.syntax()); - - builder.replace(old_parent_range, new_parent.to_string()); + let mut editor = builder.make_editor(use_.syntax()); + // Remove the use tree from the current use item + tree.remove(&mut editor); + // Insert a newline and indentation, followed by the new use item + editor.insert_all( + Position::after(use_.syntax()), + vec![ + make.whitespace(&format!("\n{}", IndentLevel::from_node(use_.syntax()))) + .syntax_element(), + new_use.syntax().syntax_element(), + ], + ); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }) } @@ -230,4 +244,19 @@ pub use std::fmt::Display; use std::process;", ); } + + #[test] + fn unmerge_use_item_with_attributes() { + check_assist( + unmerge_use, + r" +#[allow(deprecated)] +use foo::{bar, baz$0};", + r" +#[allow(deprecated)] +use foo::{bar}; +#[allow(deprecated)] +use foo::baz;", + ); + } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 1854000d3db2..1894a3218f85 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -107,6 +107,20 @@ impl SyntaxFactory { ast } + pub fn use_(&self, visibility: Option, use_tree: ast::UseTree) -> ast::Use { + make::use_(visibility, use_tree).clone_for_update() + } + + pub fn use_tree( + &self, + path: ast::Path, + use_tree_list: Option, + alias: Option, + add_star: bool, + ) -> ast::UseTree { + make::use_tree(path, use_tree_list, alias, add_star).clone_for_update() + } + pub fn path_unqualified(&self, segment: ast::PathSegment) -> ast::Path { let ast = make::path_unqualified(segment.clone()).clone_for_update(); diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs index 58200189c46b..31caf618be90 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs @@ -20,6 +20,7 @@ mod edit_algo; mod edits; mod mapping; +pub use edits::Removable; pub use mapping::{SyntaxMapping, SyntaxMappingBuilder}; #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs index 350cb3e2544f..d66ea8aa28cf 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs @@ -1,7 +1,8 @@ //! Structural editing for ast using `SyntaxEditor` use crate::{ - Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T, + AstToken, Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T, + algo::neighbor, ast::{ self, AstNode, Fn, GenericParam, HasGenericParams, HasName, edit::IndentLevel, make, syntax_factory::SyntaxFactory, @@ -143,6 +144,53 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Some(()) } +pub trait Removable: AstNode { + fn remove(&self, editor: &mut SyntaxEditor); +} + +impl Removable for ast::Use { + fn remove(&self, editor: &mut SyntaxEditor) { + let make = SyntaxFactory::without_mappings(); + + let next_ws = self + .syntax() + .next_sibling_or_token() + .and_then(|it| it.into_token()) + .and_then(ast::Whitespace::cast); + if let Some(next_ws) = next_ws { + let ws_text = next_ws.syntax().text(); + if let Some(rest) = ws_text.strip_prefix('\n') { + if rest.is_empty() { + editor.delete(next_ws.syntax()); + } else { + editor.replace(next_ws.syntax(), make.whitespace(rest)); + } + } + } + + editor.delete(self.syntax()); + } +} + +impl Removable for ast::UseTree { + fn remove(&self, editor: &mut SyntaxEditor) { + for dir in [Direction::Next, Direction::Prev] { + if let Some(next_use_tree) = neighbor(self, dir) { + let separators = self + .syntax() + .siblings_with_tokens(dir) + .skip(1) + .take_while(|it| it.as_node() != Some(next_use_tree.syntax())); + for sep in separators { + editor.delete(sep); + } + break; + } + } + editor.delete(self.syntax()); + } +} + #[cfg(test)] mod tests { use parser::Edition; From 30eeab038115da3932a7932b82f14f0a563e6011 Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Fri, 28 Mar 2025 15:12:21 +0530 Subject: [PATCH 027/262] chore: rename `unmerge_use` to `unmerge_imports` Signed-off-by: Prajwal S N --- .../{unmerge_use.rs => unmerge_imports.rs} | 56 +++++++++---------- .../crates/ide-assists/src/lib.rs | 4 +- .../crates/ide-assists/src/tests/generated.rs | 28 +++++----- 3 files changed, 44 insertions(+), 44 deletions(-) rename src/tools/rust-analyzer/crates/ide-assists/src/handlers/{unmerge_use.rs => unmerge_imports.rs} (82%) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs similarity index 82% rename from src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs rename to src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs index 558e6e0697ea..c066f41ca47b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs @@ -12,9 +12,9 @@ use crate::{ assist_context::{AssistContext, Assists}, }; -// Assist: unmerge_use +// Assist: unmerge_imports // -// Extracts single use item from use list. +// Extracts a use item from a use list into a standalone use list. // // ``` // use std::fmt::{Debug, Display$0}; @@ -24,12 +24,12 @@ use crate::{ // use std::fmt::{Debug}; // use std::fmt::Display; // ``` -pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { +pub(crate) fn unmerge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let tree = ctx.find_node_at_offset::()?; let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?; if tree_list.use_trees().count() < 2 { - cov_mark::hit!(skip_single_use_item); + cov_mark::hit!(skip_single_import); return None; } @@ -43,7 +43,7 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< }; let target = tree.syntax().text_range(); - acc.add(AssistId::refactor_rewrite("unmerge_use"), label, target, |builder| { + acc.add(AssistId::refactor_rewrite("unmerge_imports"), label, target, |builder| { let make = SyntaxFactory::with_mappings(); let new_use = make.use_( use_.visibility(), @@ -94,22 +94,22 @@ mod tests { use super::*; #[test] - fn skip_single_use_item() { - cov_mark::check!(skip_single_use_item); + fn skip_single_import() { + cov_mark::check!(skip_single_import); check_assist_not_applicable( - unmerge_use, + unmerge_imports, r" use std::fmt::Debug$0; ", ); check_assist_not_applicable( - unmerge_use, + unmerge_imports, r" use std::fmt::{Debug$0}; ", ); check_assist_not_applicable( - unmerge_use, + unmerge_imports, r" use std::fmt::Debug as Dbg$0; ", @@ -119,7 +119,7 @@ use std::fmt::Debug as Dbg$0; #[test] fn skip_single_glob_import() { check_assist_not_applicable( - unmerge_use, + unmerge_imports, r" use std::fmt::*$0; ", @@ -127,9 +127,9 @@ use std::fmt::*$0; } #[test] - fn unmerge_use_item() { + fn unmerge_import() { check_assist( - unmerge_use, + unmerge_imports, r" use std::fmt::{Debug, Display$0}; ", @@ -140,7 +140,7 @@ use std::fmt::Display; ); check_assist( - unmerge_use, + unmerge_imports, r" use std::fmt::{Debug, format$0, Display}; ", @@ -154,7 +154,7 @@ use std::fmt::format; #[test] fn unmerge_glob_import() { check_assist( - unmerge_use, + unmerge_imports, r" use std::fmt::{*$0, Display}; ", @@ -166,9 +166,9 @@ use std::fmt::*; } #[test] - fn unmerge_renamed_use_item() { + fn unmerge_renamed_import() { check_assist( - unmerge_use, + unmerge_imports, r" use std::fmt::{Debug, Display as Disp$0}; ", @@ -180,9 +180,9 @@ use std::fmt::Display as Disp; } #[test] - fn unmerge_indented_use_item() { + fn unmerge_indented_import() { check_assist( - unmerge_use, + unmerge_imports, r" mod format { use std::fmt::{Debug, Display$0 as Disp, format}; @@ -198,9 +198,9 @@ mod format { } #[test] - fn unmerge_nested_use_item() { + fn unmerge_nested_import() { check_assist( - unmerge_use, + unmerge_imports, r" use foo::bar::{baz::{qux$0, foobar}, barbaz}; ", @@ -210,7 +210,7 @@ use foo::bar::baz::qux; ", ); check_assist( - unmerge_use, + unmerge_imports, r" use foo::bar::{baz$0::{qux, foobar}, barbaz}; ", @@ -222,9 +222,9 @@ use foo::bar::baz::{qux, foobar}; } #[test] - fn unmerge_use_item_with_visibility() { + fn unmerge_import_with_visibility() { check_assist( - unmerge_use, + unmerge_imports, r" pub use std::fmt::{Debug, Display$0}; ", @@ -236,9 +236,9 @@ pub use std::fmt::Display; } #[test] - fn unmerge_use_item_on_self() { + fn unmerge_import_on_self() { check_assist( - unmerge_use, + unmerge_imports, r"use std::process::{Command, self$0};", r"use std::process::{Command}; use std::process;", @@ -246,9 +246,9 @@ use std::process;", } #[test] - fn unmerge_use_item_with_attributes() { + fn unmerge_import_with_attributes() { check_assist( - unmerge_use, + unmerge_imports, r" #[allow(deprecated)] use foo::{bar, baz$0};", diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index a157483a449c..627ed37b04e5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -222,8 +222,8 @@ mod handlers { mod toggle_async_sugar; mod toggle_ignore; mod toggle_macro_delimiter; + mod unmerge_imports; mod unmerge_match_arm; - mod unmerge_use; mod unnecessary_async; mod unqualify_method_call; mod unwrap_block; @@ -363,7 +363,7 @@ mod handlers { toggle_ignore::toggle_ignore, toggle_macro_delimiter::toggle_macro_delimiter, unmerge_match_arm::unmerge_match_arm, - unmerge_use::unmerge_use, + unmerge_imports::unmerge_imports, unnecessary_async::unnecessary_async, unqualify_method_call::unqualify_method_call, unwrap_block::unwrap_block, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 00a9d35c3107..54d060cc7909 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -3339,6 +3339,20 @@ sth!{ } ) } +#[test] +fn doctest_unmerge_imports() { + check_doc_test( + "unmerge_imports", + r#####" +use std::fmt::{Debug, Display$0}; +"#####, + r#####" +use std::fmt::{Debug}; +use std::fmt::Display; +"#####, + ) +} + #[test] fn doctest_unmerge_match_arm() { check_doc_test( @@ -3365,20 +3379,6 @@ fn handle(action: Action) { ) } -#[test] -fn doctest_unmerge_use() { - check_doc_test( - "unmerge_use", - r#####" -use std::fmt::{Debug, Display$0}; -"#####, - r#####" -use std::fmt::{Debug}; -use std::fmt::Display; -"#####, - ) -} - #[test] fn doctest_unnecessary_async() { check_doc_test( From 32bf2ac529495e105be95b82909a3105b3e4698e Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Fri, 28 Mar 2025 15:57:10 +0530 Subject: [PATCH 028/262] refactor: migrate `merge_imports` to syntax editor Co-authored-by: Tarek Signed-off-by: Prajwal S N --- .../ide-assists/src/handlers/merge_imports.rs | 70 +++++++------------ 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs index b7f7cb9cb01c..6bf7f5849148 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs @@ -1,14 +1,14 @@ use either::Either; use ide_db::imports::{ insert_use::{ImportGranularity, InsertUseConfig}, - merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees, try_normalize_use_tree}, + merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees}, }; -use itertools::Itertools; use syntax::{ AstNode, SyntaxElement, SyntaxNode, algo::neighbor, - ast::{self, edit_in_place::Removable}, - match_ast, ted, + ast::{self, syntax_factory::SyntaxFactory}, + match_ast, + syntax_editor::Removable, }; use crate::{ @@ -69,49 +69,32 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio (selection_range, edits?) }; - acc.add(AssistId::refactor_rewrite("merge_imports"), "Merge imports", target, |builder| { - let edits_mut: Vec = edits - .into_iter() - .map(|it| match it { - Remove(Either::Left(it)) => Remove(Either::Left(builder.make_mut(it))), - Remove(Either::Right(it)) => Remove(Either::Right(builder.make_mut(it))), - Replace(old, new) => Replace(builder.make_syntax_mut(old), new), - }) - .collect(); - for edit in edits_mut { - match edit { - Remove(it) => it.as_ref().either(Removable::remove, Removable::remove), - Replace(old, new) => { - ted::replace(old, &new); + let parent_node = match ctx.covering_element() { + SyntaxElement::Node(n) => n, + SyntaxElement::Token(t) => t.parent()?, + }; - // If there's a selection and we're replacing a use tree in a tree list, - // normalize the parent use tree if it only contains the merged subtree. - if !ctx.has_empty_selection() { - let normalized_use_tree = ast::UseTree::cast(new) - .as_ref() - .and_then(ast::UseTree::parent_use_tree_list) - .and_then(|use_tree_list| { - if use_tree_list.use_trees().collect_tuple::<(_,)>().is_some() { - Some(use_tree_list.parent_use_tree()) - } else { - None - } - }) - .and_then(|target_tree| { - try_normalize_use_tree( - &target_tree, - ctx.config.insert_use.granularity.into(), - ) - .map(|top_use_tree_flat| (target_tree, top_use_tree_flat)) - }); - if let Some((old_tree, new_tree)) = normalized_use_tree { - cov_mark::hit!(replace_parent_with_normalized_use_tree); - ted::replace(old_tree.syntax(), new_tree.syntax()); - } + acc.add(AssistId::refactor_rewrite("merge_imports"), "Merge imports", target, |builder| { + let make = SyntaxFactory::with_mappings(); + let mut editor = builder.make_editor(&parent_node); + + for edit in edits { + match edit { + Remove(it) => { + let node = it.as_ref(); + if let Some(left) = node.left() { + left.remove(&mut editor); + } else if let Some(right) = node.right() { + right.remove(&mut editor); } } + Replace(old, new) => { + editor.replace(old, &new); + } } } + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }) } @@ -723,11 +706,10 @@ use std::{ ); cov_mark::check!(merge_with_selected_use_tree_neighbors); - cov_mark::check!(replace_parent_with_normalized_use_tree); check_assist( merge_imports, r"use std::$0{fmt::Display, fmt::Debug}$0;", - r"use std::fmt::{Debug, Display};", + r"use std::{fmt::{Debug, Display}};", ); } From f479012d0ee77bb8a2a19f6ffb096860498ca5c2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 28 Apr 2025 17:16:28 +0200 Subject: [PATCH 029/262] refactor: De-arc lang item queries --- .../rust-analyzer/crates/hir-def/src/db.rs | 8 +- .../crates/hir-def/src/lang_item.rs | 199 ++++++++++-------- .../crates/hir-ty/src/autoderef.rs | 6 +- .../crates/hir-ty/src/chalk_db.rs | 24 +-- .../crates/hir-ty/src/chalk_ext.rs | 7 +- .../crates/hir-ty/src/diagnostics/expr.rs | 5 +- .../crates/hir-ty/src/display.rs | 14 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 7 +- .../crates/hir-ty/src/dyn_compatibility.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 4 +- .../crates/hir-ty/src/infer/coerce.rs | 9 +- .../crates/hir-ty/src/infer/mutability.rs | 12 +- .../crates/hir-ty/src/infer/unify.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 15 +- .../crates/hir-ty/src/mir/eval.rs | 25 +-- .../crates/hir-ty/src/mir/eval/shim.rs | 21 +- .../crates/hir-ty/src/mir/lower.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 11 +- .../rust-analyzer/crates/hir-ty/src/utils.rs | 3 +- .../rust-analyzer/crates/hir/src/display.rs | 3 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 54 ++--- .../crates/hir/src/source_analyzer.rs | 8 +- .../rust-analyzer/crates/ide/src/hover.rs | 4 +- 23 files changed, 194 insertions(+), 261 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 34cf42d02bdb..2cbdbe16f9bb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -22,7 +22,7 @@ use crate::{ hir::generics::GenericParams, import_map::ImportMap, item_tree::{AttrOwner, ItemTree}, - lang_item::{self, LangItem, LangItemTarget, LangItems}, + lang_item::{self, LangItem}, nameres::{ DefMap, LocalDefMap, assoc::{ImplItems, TraitItems}, @@ -325,9 +325,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { // endregion:attrs - #[salsa::invoke(LangItems::lang_item_query)] - fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option; - #[salsa::invoke(ImportMap::import_map_query)] fn import_map(&self, krate: Crate) -> Arc; @@ -349,9 +346,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { // endregion:visibilities - #[salsa::invoke(LangItems::crate_lang_items_query)] - fn crate_lang_items(&self, krate: Crate) -> Option>; - #[salsa::invoke(crate::lang_item::notable_traits_in_deps)] fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>; #[salsa::invoke(crate::lang_item::crate_notable_traits)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 5431ec9679c5..6a4ac199b340 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -83,6 +83,91 @@ impl LangItemTarget { } } +/// Salsa query. This will look for lang items in a specific crate. +#[salsa::tracked(return_ref)] +pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option> { + let _p = tracing::info_span!("crate_lang_items_query").entered(); + + let mut lang_items = LangItems::default(); + + let crate_def_map = db.crate_def_map(krate); + + for (_, module_data) in crate_def_map.modules() { + for impl_def in module_data.scope.impls() { + lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef); + for &(_, assoc) in db.impl_items(impl_def).items.iter() { + match assoc { + AssocItemId::FunctionId(f) => { + lang_items.collect_lang_item(db, f, LangItemTarget::Function) + } + AssocItemId::TypeAliasId(t) => { + lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias) + } + AssocItemId::ConstId(_) => (), + } + } + } + + for def in module_data.scope.declarations() { + match def { + ModuleDefId::TraitId(trait_) => { + lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait); + db.trait_items(trait_).items.iter().for_each(|&(_, assoc_id)| match assoc_id { + AssocItemId::FunctionId(f) => { + lang_items.collect_lang_item(db, f, LangItemTarget::Function); + } + AssocItemId::TypeAliasId(alias) => { + lang_items.collect_lang_item(db, alias, LangItemTarget::TypeAlias) + } + AssocItemId::ConstId(_) => {} + }); + } + ModuleDefId::AdtId(AdtId::EnumId(e)) => { + lang_items.collect_lang_item(db, e, LangItemTarget::EnumId); + db.enum_variants(e).variants.iter().for_each(|&(id, _)| { + lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant); + }); + } + ModuleDefId::AdtId(AdtId::StructId(s)) => { + lang_items.collect_lang_item(db, s, LangItemTarget::Struct); + } + ModuleDefId::AdtId(AdtId::UnionId(u)) => { + lang_items.collect_lang_item(db, u, LangItemTarget::Union); + } + ModuleDefId::FunctionId(f) => { + lang_items.collect_lang_item(db, f, LangItemTarget::Function); + } + ModuleDefId::StaticId(s) => { + lang_items.collect_lang_item(db, s, LangItemTarget::Static); + } + ModuleDefId::TypeAliasId(t) => { + lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias); + } + _ => {} + } + } + } + + if lang_items.items.is_empty() { None } else { Some(Box::new(lang_items)) } +} + +/// Salsa query. Look for a lang item, starting from the specified crate and recursively +/// traversing its dependencies. +#[salsa::tracked] +pub fn lang_item( + db: &dyn DefDatabase, + start_crate: Crate, + item: LangItem, +) -> Option { + let _p = tracing::info_span!("lang_item_query").entered(); + if let Some(target) = + crate_lang_items(db, start_crate).as_ref().and_then(|it| it.items.get(&item).copied()) + { + return Some(target); + } + start_crate.data(db).dependencies.iter().find_map(|dep| lang_item(db, dep.crate_id, item)) +} + #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct LangItems { items: FxHashMap, @@ -93,96 +178,6 @@ impl LangItems { self.items.get(&item).copied() } - /// Salsa query. This will look for lang items in a specific crate. - pub(crate) fn crate_lang_items_query( - db: &dyn DefDatabase, - krate: Crate, - ) -> Option> { - let _p = tracing::info_span!("crate_lang_items_query").entered(); - - let mut lang_items = LangItems::default(); - - let crate_def_map = db.crate_def_map(krate); - - for (_, module_data) in crate_def_map.modules() { - for impl_def in module_data.scope.impls() { - lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef); - for &(_, assoc) in db.impl_items(impl_def).items.iter() { - match assoc { - AssocItemId::FunctionId(f) => { - lang_items.collect_lang_item(db, f, LangItemTarget::Function) - } - AssocItemId::TypeAliasId(t) => { - lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias) - } - AssocItemId::ConstId(_) => (), - } - } - } - - for def in module_data.scope.declarations() { - match def { - ModuleDefId::TraitId(trait_) => { - lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait); - db.trait_items(trait_).items.iter().for_each( - |&(_, assoc_id)| match assoc_id { - AssocItemId::FunctionId(f) => { - lang_items.collect_lang_item(db, f, LangItemTarget::Function); - } - AssocItemId::TypeAliasId(alias) => lang_items.collect_lang_item( - db, - alias, - LangItemTarget::TypeAlias, - ), - AssocItemId::ConstId(_) => {} - }, - ); - } - ModuleDefId::AdtId(AdtId::EnumId(e)) => { - lang_items.collect_lang_item(db, e, LangItemTarget::EnumId); - db.enum_variants(e).variants.iter().for_each(|&(id, _)| { - lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant); - }); - } - ModuleDefId::AdtId(AdtId::StructId(s)) => { - lang_items.collect_lang_item(db, s, LangItemTarget::Struct); - } - ModuleDefId::AdtId(AdtId::UnionId(u)) => { - lang_items.collect_lang_item(db, u, LangItemTarget::Union); - } - ModuleDefId::FunctionId(f) => { - lang_items.collect_lang_item(db, f, LangItemTarget::Function); - } - ModuleDefId::StaticId(s) => { - lang_items.collect_lang_item(db, s, LangItemTarget::Static); - } - ModuleDefId::TypeAliasId(t) => { - lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias); - } - _ => {} - } - } - } - - if lang_items.items.is_empty() { None } else { Some(Arc::new(lang_items)) } - } - - /// Salsa query. Look for a lang item, starting from the specified crate and recursively - /// traversing its dependencies. - pub(crate) fn lang_item_query( - db: &dyn DefDatabase, - start_crate: Crate, - item: LangItem, - ) -> Option { - let _p = tracing::info_span!("lang_item_query").entered(); - if let Some(target) = - db.crate_lang_items(start_crate).and_then(|it| it.items.get(&item).copied()) - { - return Some(target); - } - start_crate.data(db).dependencies.iter().find_map(|dep| db.lang_item(dep.crate_id, item)) - } - fn collect_lang_item( &mut self, db: &dyn DefDatabase, @@ -269,18 +264,38 @@ macro_rules! language_item_table { } impl LangItem { + pub fn resolve_function(self, db: &dyn DefDatabase, start_crate: Crate) -> Option { + lang_item(db, start_crate, self).and_then(|t| t.as_function()) + } + + pub fn resolve_trait(self, db: &dyn DefDatabase, start_crate: Crate) -> Option { + lang_item(db, start_crate, self).and_then(|t| t.as_trait()) + } + + pub fn resolve_enum(self, db: &dyn DefDatabase, start_crate: Crate) -> Option { + lang_item(db, start_crate, self).and_then(|t| t.as_enum()) + } + + pub fn resolve_type_alias( + self, + db: &dyn DefDatabase, + start_crate: Crate, + ) -> Option { + lang_item(db, start_crate, self).and_then(|t| t.as_type_alias()) + } + /// Opposite of [`LangItem::name`] pub fn from_name(name: &hir_expand::name::Name) -> Option { Self::from_symbol(name.symbol()) } pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option { - let t = db.lang_item(start_crate, *self)?; + let t = lang_item(db, start_crate, *self)?; Some(Path::LangItem(t, None)) } pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option { - let t = db.lang_item(start_crate, *self)?; + let t = lang_item(db, start_crate, *self)?; Some(Path::LangItem(t, Some(seg))) } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index 711544545681..7acc9456ec9c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -198,15 +198,13 @@ pub(crate) fn deref_by_trait( // blanked impl on `Deref`. #[expect(clippy::overly_complex_bool_expr)] if use_receiver_trait && false { - if let Some(receiver) = - db.lang_item(table.trait_env.krate, LangItem::Receiver).and_then(|l| l.as_trait()) - { + if let Some(receiver) = LangItem::Receiver.resolve_trait(db, table.trait_env.krate) { return Some(receiver); } } // Old rustc versions might not have `Receiver` trait. // Fallback to `Deref` if they don't - db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait()) + LangItem::Deref.resolve_trait(db, table.trait_env.krate) }; let trait_id = trait_id()?; let target = diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 2aa9401eefa9..376daccbdae8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -16,7 +16,7 @@ use hir_def::{ AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, VariantId, hir::Movability, - lang_item::{LangItem, LangItemTarget}, + lang_item::LangItem, signatures::{ImplFlags, StructFlags, TraitFlags}, }; @@ -262,10 +262,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { well_known_trait: rust_ir::WellKnownTrait, ) -> Option> { let lang_attr = lang_item_from_well_known_trait(well_known_trait); - let trait_ = match self.db.lang_item(self.krate, lang_attr) { - Some(LangItemTarget::Trait(trait_)) => trait_, - _ => return None, - }; + let trait_ = lang_attr.resolve_trait(self.db, self.krate)?; Some(to_chalk_trait_id(trait_)) } @@ -306,11 +303,8 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { chalk_ir::Binders::new(binders, bound) } crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { - if let Some((future_trait, future_output)) = self - .db - .lang_item(self.krate, LangItem::Future) - .and_then(|item| item.as_trait()) - .and_then(|trait_| { + if let Some((future_trait, future_output)) = + LangItem::Future.resolve_trait(self.db, self.krate).and_then(|trait_| { let alias = self .db .trait_items(trait_) @@ -338,10 +332,7 @@ impl chalk_solve::RustIrDatabase for ChalkContext<'_> { }); let mut binder = vec![]; binder.push(crate::wrap_empty_binders(impl_bound)); - let sized_trait = self - .db - .lang_item(self.krate, LangItem::Sized) - .and_then(|item| item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(self.db, self.krate); if let Some(sized_trait_) = sized_trait { let sized_bound = WhereClause::Implemented(TraitRef { trait_id: to_chalk_trait_id(sized_trait_), @@ -660,9 +651,8 @@ pub(crate) fn associated_ty_data_query( } if !ctx.unsized_types.contains(&self_ty) { - let sized_trait = db - .lang_item(resolver.krate(), LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id)); + let sized_trait = + LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id); let sized_bound = sized_trait.into_iter().map(|sized_trait| { let trait_bound = rust_ir::TraitBound { trait_id: sized_trait, args_no_self: Default::default() }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs index 0f0cf6ae7ae6..aabc4c4234db 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs @@ -251,9 +251,7 @@ impl TyExt for Ty { match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { let krate = def.module(db).krate(); - if let Some(future_trait) = - db.lang_item(krate, LangItem::Future).and_then(|item| item.as_trait()) - { + if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) { // This is only used by type walking. // Parameters will be walked outside, and projection predicate is not used. // So just provide the Future trait. @@ -364,8 +362,7 @@ impl TyExt for Ty { fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool { let crate_id = owner.module(db).krate(); - let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|it| it.as_trait()) - else { + let Some(copy_trait) = LangItem::Copy.resolve_trait(db, crate_id) else { return false; }; let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 5e3d88058962..57106412765a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -482,9 +482,8 @@ struct FilterMapNextChecker { impl FilterMapNextChecker { fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self { // Find and store the FunctionIds for Iterator::filter_map and Iterator::next - let (next_function_id, filter_map_function_id) = match db - .lang_item(resolver.krate(), LangItem::IteratorNext) - .and_then(|it| it.as_function()) + let (next_function_id, filter_map_function_id) = match LangItem::IteratorNext + .resolve_function(db, resolver.krate()) { Some(next_function_id) => ( Some(next_function_id), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index f62e4bb4f806..e810467b994a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -19,7 +19,7 @@ use hir_def::{ hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_scope::ItemInNs, item_tree::FieldsShape, - lang_item::{LangItem, LangItemTarget}, + lang_item::LangItem, nameres::DefMap, signatures::VariantFields, type_ref::{ @@ -1348,9 +1348,8 @@ impl HirDisplay for Ty { )?; } ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => { - let future_trait = db - .lang_item(body.module(db).krate(), LangItem::Future) - .and_then(LangItemTarget::as_trait); + let future_trait = + LangItem::Future.resolve_trait(db, body.module(db).krate()); let output = future_trait.and_then(|t| { db.trait_items(t) .associated_type_by_name(&Name::new_symbol_root(sym::Output)) @@ -1728,9 +1727,7 @@ impl SizedByDefault { match self { Self::NotSized => false, Self::Sized { anchor } => { - let sized_trait = db - .lang_item(anchor, LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(db, anchor); Some(trait_) == sized_trait } } @@ -1895,8 +1892,7 @@ fn write_bounds_like_dyn_trait( write!(f, ">")?; } if let SizedByDefault::Sized { anchor } = default_sized { - let sized_trait = - f.db.lang_item(anchor, LangItem::Sized).and_then(|lang_item| lang_item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor); if !is_sized { if !first { write!(f, " + ")?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 9823c854d5b3..70763759ef0e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -19,9 +19,7 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool { AdtId::StructId(id) => db.lookup_intern_struct(id).container, AdtId::UnionId(id) => db.lookup_intern_union(id).container, }; - let Some(drop_trait) = - db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait()) - else { + let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate()) else { return false; }; let impls = match module.containing_block() { @@ -181,8 +179,7 @@ fn projection_has_drop_glue( } fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc) -> bool { - let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait()) - else { + let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else { return false; }; let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 80b18473907d..fecaafb4c2e8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -124,7 +124,7 @@ pub fn dyn_compatibility_of_trait_query( fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool { let krate = def.module(db).krate(); - let Some(sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else { + let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else { return false; }; @@ -491,8 +491,8 @@ fn receiver_is_dispatchable( let krate = func.module(db).krate(); let traits = ( - db.lang_item(krate, LangItem::Unsize).and_then(|it| it.as_trait()), - db.lang_item(krate, LangItem::DispatchFromDyn).and_then(|it| it.as_trait()), + LangItem::Unsize.resolve_trait(db, krate), + LangItem::DispatchFromDyn.resolve_trait(db, krate), ); let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else { return false; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 790914fdaf2a..f0ec31db8bb9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -39,7 +39,7 @@ use hir_def::{ builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, - lang_item::{LangItem, LangItemTarget}, + lang_item::{LangItem, LangItemTarget, lang_item}, layout::Integer, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, signatures::{ConstSignature, StaticSignature}, @@ -1801,7 +1801,7 @@ impl<'a> InferenceContext<'a> { fn resolve_lang_item(&self, item: LangItem) -> Option { let krate = self.resolver.krate(); - self.db.lang_item(krate, item) + lang_item(self.db, krate, item) } fn resolve_output_on(&self, trait_: TraitId) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index 847dd43a02d6..39bd90849fe8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -8,10 +8,7 @@ use std::iter; use chalk_ir::{BoundVar, Goal, Mutability, TyKind, TyVariableKind, cast::Cast}; -use hir_def::{ - hir::ExprId, - lang_item::{LangItem, LangItemTarget}, -}; +use hir_def::{hir::ExprId, lang_item::LangItem}; use stdx::always; use triomphe::Arc; @@ -701,8 +698,8 @@ impl InferenceTable<'_> { reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone()); let krate = self.trait_env.krate; - let coerce_unsized_trait = match self.db.lang_item(krate, LangItem::CoerceUnsized) { - Some(LangItemTarget::Trait(trait_)) => trait_, + let coerce_unsized_trait = match LangItem::CoerceUnsized.resolve_trait(self.db, krate) { + Some(trait_) => trait_, _ => return Err(TypeError), }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index cf0152ecd263..ac450c0b5591 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -126,10 +126,8 @@ impl InferenceContext<'_> { &Expr::Index { base, index } => { if mutability == Mutability::Mut { if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) { - if let Some(index_trait) = self - .db - .lang_item(self.table.trait_env.krate, LangItem::IndexMut) - .and_then(|l| l.as_trait()) + if let Some(index_trait) = + LangItem::IndexMut.resolve_trait(self.db, self.table.trait_env.krate) { if let Some(index_fn) = self .db @@ -183,10 +181,8 @@ impl InferenceContext<'_> { let mut mutability = mutability; if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) { if mutability == Mutability::Mut { - if let Some(deref_trait) = self - .db - .lang_item(self.table.trait_env.krate, LangItem::DerefMut) - .and_then(|l| l.as_trait()) + if let Some(deref_trait) = + LangItem::DerefMut.resolve_trait(self.db, self.table.trait_env.krate) { let ty = self.result.type_of_expr.get(*expr); let is_mut_ptr = ty.is_some_and(|ty| { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index 60aa9b5a17a8..d921afeb9879 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -1024,11 +1024,7 @@ impl<'a> InferenceTable<'a> { } } - let Some(sized) = self - .db - .lang_item(self.trait_env.krate, LangItem::Sized) - .and_then(|sized| sized.as_trait()) - else { + let Some(sized) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else { return false; }; let sized_pred = WhereClause::Implemented(TraitRef { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index e4688d044e98..6d7e58bea6a2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -590,10 +590,7 @@ impl<'a> TyLoweringContext<'a> { } } &TypeBound::Path(path, TraitBoundModifier::Maybe) => { - let sized_trait = self - .db - .lang_item(self.resolver.krate(), LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate()); // Don't lower associated type bindings as the only possible relaxed trait bound // `?Sized` has no of them. // If we got another trait here ignore the bound completely. @@ -736,10 +733,8 @@ impl<'a> TyLoweringContext<'a> { } if !ctx.unsized_types.contains(&self_ty) { - let sized_trait = ctx - .db - .lang_item(krate, LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id)); + let sized_trait = + LangItem::Sized.resolve_trait(ctx.db, krate).map(to_chalk_trait_id); let sized_clause = sized_trait.map(|trait_id| { let clause = WhereClause::Implemented(TraitRef { trait_id, @@ -1188,9 +1183,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>( substitution: &'subst Substitution, resolver: &Resolver, ) -> Option + Captures<'a> + Captures<'subst>> { - let sized_trait = db - .lang_item(resolver.krate(), LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?; + let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id)?; let trait_self_idx = trait_self_param_idx(db, def); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 386226b16d5d..286381ce99cf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -655,22 +655,15 @@ impl Evaluator<'_> { mir_or_dyn_index_cache: RefCell::new(Default::default()), unused_locals_store: RefCell::new(Default::default()), cached_ptr_size, - cached_fn_trait_func: db - .lang_item(crate_id, LangItem::Fn) - .and_then(|x| x.as_trait()) + cached_fn_trait_func: LangItem::Fn + .resolve_trait(db, crate_id) .and_then(|x| db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call))), - cached_fn_mut_trait_func: db - .lang_item(crate_id, LangItem::FnMut) - .and_then(|x| x.as_trait()) - .and_then(|x| { - db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut)) - }), - cached_fn_once_trait_func: db - .lang_item(crate_id, LangItem::FnOnce) - .and_then(|x| x.as_trait()) - .and_then(|x| { - db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once)) - }), + cached_fn_mut_trait_func: LangItem::FnMut.resolve_trait(db, crate_id).and_then(|x| { + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut)) + }), + cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| { + db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once)) + }), }) } @@ -2811,7 +2804,7 @@ impl Evaluator<'_> { span: MirSpan, ) -> Result<()> { let Some(drop_fn) = (|| { - let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?; + let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?; self.db.trait_items(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop)) })() else { // in some tests we don't have drop trait in minicore, and diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 4de44cfd02e9..26ef95d264be 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -6,7 +6,6 @@ use std::cmp::{self, Ordering}; use chalk_ir::TyKind; use hir_def::{ builtin_type::{BuiltinInt, BuiltinUint}, - lang_item::LangItemTarget, resolver::HasResolver, }; use hir_expand::name::Name; @@ -156,8 +155,8 @@ impl Evaluator<'_> { if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) { let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db); - let Some(hir_def::lang_item::LangItemTarget::Function(const_panic_fmt)) = - self.db.lang_item(resolver.krate(), LangItem::ConstPanicFmt) + let Some(const_panic_fmt) = + LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate()) else { not_supported!("const_panic_fmt lang item not found or not a function"); }; @@ -1257,12 +1256,12 @@ impl Evaluator<'_> { let addr = tuple.interval.addr.offset(offset); args.push(IntervalAndTy::new(addr, field, self, locals)?); } - if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) { - if let Some(def) = target.as_trait().and_then(|it| { - self.db - .trait_items(it) - .method_by_name(&Name::new_symbol_root(sym::call_once)) - }) { + if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id) { + if let Some(def) = self + .db + .trait_items(target) + .method_by_name(&Name::new_symbol_root(sym::call_once)) + { self.exec_fn_trait( def, &args, @@ -1376,9 +1375,7 @@ impl Evaluator<'_> { } } } - if let Some(LangItemTarget::EnumId(e)) = - self.db.lang_item(self.crate_id, LangItem::Ordering) - { + if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) { let ty = self.db.ty(e.into()); let r = self .compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 557027756f39..ebccb11ce0ca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -13,7 +13,7 @@ use hir_def::{ Pat, PatId, RecordFieldPat, RecordLitField, }, item_tree::FieldsShape, - lang_item::{LangItem, LangItemTarget}, + lang_item::{LangItem, LangItemTarget, lang_item}, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, }; use hir_expand::name::Name; @@ -1727,7 +1727,7 @@ impl<'ctx> MirLowerCtx<'ctx> { fn resolve_lang_item(&self, item: LangItem) -> Result { let crate_id = self.owner.module(self.db).krate(); - self.db.lang_item(crate_id, item).ok_or(MirLowerError::LangItemNotFound(item)) + lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item)) } fn lower_block_to_place( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index a5c195d4086a..f9f8776cff7c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -8,10 +8,7 @@ use chalk_recursive::Cache; use chalk_solve::{Solver, logging_db::LoggingRustIrDatabase, rust_ir}; use base_db::Crate; -use hir_def::{ - BlockId, TraitId, - lang_item::{LangItem, LangItemTarget}, -}; +use hir_def::{BlockId, TraitId, lang_item::LangItem}; use hir_expand::name::Name; use intern::sym; use span::Edition; @@ -292,10 +289,6 @@ impl FnTrait { } pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option { - let target = db.lang_item(krate, self.lang_item())?; - match target { - LangItemTarget::Trait(t) => Some(t), - _ => None, - } + self.lang_item().resolve_trait(db, krate) } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 198f715a6db2..1e0ff423ded6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -36,8 +36,7 @@ use crate::{ pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator + '_ { [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce] .into_iter() - .filter_map(move |lang| db.lang_item(krate, lang)) - .flat_map(|it| it.as_trait()) + .filter_map(move |lang| lang.resolve_trait(db, krate)) } /// Returns an iterator over the direct super traits (including the trait itself). diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 53817f37aa66..124ab8e274af 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -516,8 +516,7 @@ impl HirDisplay for TypeParam { return Ok(()); } - let sized_trait = - f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(f.db, krate); let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() { WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait, _ => false, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 143c13069e42..c62e4cf4497d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -53,7 +53,6 @@ use hir_def::{ generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, }, item_tree::{AttrOwner, FieldParent, ImportAlias, ItemTreeFieldId, ItemTreeNode}, - lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, nameres::{self, diagnostics::DefDiagnostic}, per_ns::PerNs, @@ -781,7 +780,7 @@ impl Module { let drop_maybe_dangle = (|| { // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper let trait_ = trait_?; - let drop_trait = db.lang_item(self.krate().into(), LangItem::Drop)?.as_trait()?; + let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?; if drop_trait != trait_.into() { return None; } @@ -2388,14 +2387,11 @@ impl Function { } let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false }; - let Some(future_trait_id) = - db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait()) + let Some(future_trait_id) = LangItem::Future.resolve_trait(db, self.ty(db).env.krate) else { return false; }; - let Some(sized_trait_id) = - db.lang_item(self.ty(db).env.krate, LangItem::Sized).and_then(|t| t.as_trait()) - else { + let Some(sized_trait_id) = LangItem::Sized.resolve_trait(db, self.ty(db).env.krate) else { return false; }; @@ -2861,9 +2857,7 @@ pub struct Trait { impl Trait { pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option { - db.lang_item(krate.into(), LangItem::from_name(name)?) - .and_then(LangItemTarget::as_trait) - .map(Into::into) + LangItem::from_name(name)?.resolve_trait(db, krate.into()).map(Into::into) } pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -4989,18 +4983,14 @@ impl Type { /// `std::future::Future` and returns the `Output` associated type. /// This function is used in `.await` syntax completion. pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option { - let trait_ = db - .lang_item(self.env.krate, LangItem::IntoFutureIntoFuture) - .and_then(|it| { - let into_future_fn = it.as_function()?; + let trait_ = LangItem::IntoFutureIntoFuture + .resolve_function(db, self.env.krate) + .and_then(|into_future_fn| { let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?; let into_future_trait = assoc_item.container_or_implemented_trait(db)?; Some(into_future_trait.id) }) - .or_else(|| { - let future_trait = db.lang_item(self.env.krate, LangItem::Future)?; - future_trait.as_trait() - })?; + .or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?; let canonical_ty = Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) }; @@ -5015,14 +5005,13 @@ impl Type { /// This does **not** resolve `IntoFuture`, only `Future`. pub fn future_output(self, db: &dyn HirDatabase) -> Option { - let future_output = - db.lang_item(self.env.krate, LangItem::FutureOutput)?.as_type_alias()?; + let future_output = LangItem::FutureOutput.resolve_type_alias(db, self.env.krate)?; self.normalize_trait_assoc_type(db, &[], future_output.into()) } /// This does **not** resolve `IntoIterator`, only `Iterator`. pub fn iterator_item(self, db: &dyn HirDatabase) -> Option { - let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?; + let iterator_trait = LangItem::Iterator.resolve_trait(db, self.env.krate)?; let iterator_item = db .trait_items(iterator_trait) .associated_type_by_name(&Name::new_symbol_root(sym::Item))?; @@ -5030,9 +5019,7 @@ impl Type { } pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool { - let Some(iterator_trait) = - db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait()) - else { + let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else { return false; }; let canonical_ty = @@ -5042,12 +5029,13 @@ impl Type { /// Resolves the projection `::IntoIter` and returns the resulting type pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option { - let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| { - let into_iter_fn = it.as_function()?; - let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?; - let into_iter_trait = assoc_item.container_or_implemented_trait(db)?; - Some(into_iter_trait.id) - })?; + let trait_ = LangItem::IntoIterIntoIter.resolve_function(db, self.env.krate).and_then( + |into_iter_fn| { + let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?; + let into_iter_trait = assoc_item.container_or_implemented_trait(db)?; + Some(into_iter_trait.id) + }, + )?; let canonical_ty = Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) }; @@ -5133,10 +5121,8 @@ impl Type { } pub fn is_copy(&self, db: &dyn HirDatabase) -> bool { - let lang_item = db.lang_item(self.env.krate, LangItem::Copy); - let copy_trait = match lang_item { - Some(LangItemTarget::Trait(it)) => it, - _ => return false, + let Some(copy_trait) = LangItem::Copy.resolve_trait(db, self.env.krate) else { + return false; }; self.impls_trait(db, copy_trait.into(), &[]) } diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 666efe8ec645..7d447116e088 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -556,8 +556,8 @@ impl SourceAnalyzer { } } - let future_trait = db.lang_item(self.resolver.krate(), LangItem::Future)?.as_trait()?; - let poll_fn = db.lang_item(self.resolver.krate(), LangItem::FuturePoll)?.as_function()?; + let future_trait = LangItem::Future.resolve_trait(db, self.resolver.krate())?; + let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?; // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself // doesn't have any generic parameters, so we skip building another subst for `poll()`. let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build(); @@ -666,7 +666,7 @@ impl SourceAnalyzer { ) -> Option { let ty = self.ty_of_expr(try_expr.expr()?)?; - let op_fn = db.lang_item(self.resolver.krate(), LangItem::TryTraitBranch)?.as_function()?; + let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?; let op_trait = match op_fn.lookup(db).container { ItemContainerId::TraitId(id) => id, _ => return None, @@ -1425,7 +1425,7 @@ impl SourceAnalyzer { lang_trait: LangItem, method_name: &Name, ) -> Option<(TraitId, FunctionId)> { - let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?; + let trait_id = lang_trait.resolve_trait(db, self.resolver.krate())?; let fn_id = db.trait_items(trait_id).method_by_name(method_name)?; Some((trait_id, fn_id)) } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 2f2d2252f844..075afcec019f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -634,9 +634,7 @@ fn walk_and_push_ty( } else if let Some(trait_) = t.as_associated_type_parent_trait(db) { push_new_def(trait_.into()); } else if let Some(tp) = t.as_type_param(db) { - let sized_trait = db - .lang_item(t.krate(db).into(), LangItem::Sized) - .and_then(|lang_item| lang_item.as_trait()); + let sized_trait = LangItem::Sized.resolve_trait(db, t.krate(db).into()); tp.trait_bounds(db) .into_iter() .filter(|&it| Some(it.into()) != sized_trait) From 2ac60bc0896b4edd09e192204e768ddbe715a573 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 26 Apr 2025 08:18:26 +0000 Subject: [PATCH 030/262] We always use the current item as parent, so no need to pass it --- compiler/rustc_ast_lowering/src/expr.rs | 3 +-- compiler/rustc_ast_lowering/src/lib.rs | 7 ++----- compiler/rustc_ast_lowering/src/pat.rs | 3 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 8e1a3cd14354..9f3aed9216c2 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -492,9 +492,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generic_args = ThinVec::new(); for (idx, arg) in args.iter().cloned().enumerate() { if legacy_args_idx.contains(&idx) { - let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); - self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, f.span); + self.create_def(node_id, None, DefKind::AnonConst, f.span); let mut visitor = WillCreateDefIdsVisitor {}; let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) { AstP(Expr { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1e14b4d6723f..b2a0b32fe261 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -494,12 +494,12 @@ enum GenericArgsMode { impl<'a, 'hir> LoweringContext<'a, 'hir> { fn create_def( &mut self, - parent: LocalDefId, node_id: ast::NodeId, name: Option, def_kind: DefKind, span: Span, ) -> LocalDefId { + let parent = self.current_hir_id_owner.def_id; debug_assert_ne!(node_id, ast::DUMMY_NODE_ID); assert!( self.opt_local_def_id(node_id).is_none(), @@ -781,7 +781,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Fresh { param, kind, .. } => { // Late resolution delegates to us the creation of the `LocalDefId`. let _def_id = self.create_def( - self.current_hir_id_owner.def_id, param, Some(kw::UnderscoreLifetime), DefKind::LifetimeParam, @@ -2107,8 +2106,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::ConstArgKind::Path(qpath) } else { // Construct an AnonConst where the expr is the "ty"'s path. - - let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); let span = self.lower_span(span); @@ -2116,7 +2113,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We're lowering a const argument that was originally thought to be a type argument, // so the def collector didn't create the def ahead of time. That's why we have to do // it here. - let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span); + let def_id = self.create_def(node_id, None, DefKind::AnonConst, span); let hir_id = self.lower_node_id(node_id); let path_expr = Expr { diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index f94d788a9b0e..2c2bae0238fd 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -517,14 +517,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, base_type: Span, ) -> &'hir hir::ConstArg<'hir> { - let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); // Add a definition for the in-band const def. // We're generating a range end that didn't exist in the AST, // so the def collector didn't create the def ahead of time. That's why we have to do // it here. - let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span); + let def_id = self.create_def(node_id, None, DefKind::AnonConst, span); let hir_id = self.lower_node_id(node_id); let unstable_span = self.mark_span_with_reason( From f831670519586bca8093d0913861d06270c7dfac Mon Sep 17 00:00:00 2001 From: Eduard Stefes Date: Mon, 28 Apr 2025 22:09:11 +0200 Subject: [PATCH 031/262] Use target-cpu=z13 on s390x codegen const vector test The default s390x cpu(z10) does not have vector support. Setting target-cpu at least to z13 enables vectorisation for s390x architecture and makes the test pass. --- tests/codegen/const-vector.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs index 1d4edc39b1c8..5a7a5433ffd7 100644 --- a/tests/codegen/const-vector.rs +++ b/tests/codegen/const-vector.rs @@ -1,4 +1,8 @@ -//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 +//@ revisions: OPT0 OPT0_S390X +//@ [OPT0] ignore-s390x +//@ [OPT0_S390X] only-s390x +//@ [OPT0] compile-flags: -C no-prepopulate-passes -Copt-level=0 +//@ [OPT0_S390X] compile-flags: -C no-prepopulate-passes -Copt-level=0 -C target-cpu=z13 // This test checks that constants of SIMD type are passed as immediate vectors. // We ensure that both vector representations (struct with fields and struct wrapping array) work. From 833f526196fffb9fc3113886a313b15f4b388691 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 28 Apr 2025 11:37:33 -0700 Subject: [PATCH 032/262] base-db: add more details to panic --- .../rust-analyzer/crates/base-db/src/lib.rs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 7f7a712577e4..1d73ba804a68 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -57,7 +57,12 @@ pub struct Files { impl Files { pub fn file_text(&self, file_id: vfs::FileId) -> FileText { - *self.files.get(&file_id).expect("Unable to fetch file; this is a bug") + match self.files.get(&file_id) { + Some(text) => *text, + None => { + panic!("Unable to fetch file text for `vfs::FileId`: {:?}; this is a bug", file_id) + } + } } pub fn set_file_text(&self, db: &mut dyn SourceDatabase, file_id: vfs::FileId, text: &str) { @@ -93,10 +98,13 @@ impl Files { /// Source root of the file. pub fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { - let source_root = self - .source_roots - .get(&source_root_id) - .expect("Unable to fetch source root id; this is a bug"); + let source_root = match self.source_roots.get(&source_root_id) { + Some(source_root) => source_root, + None => panic!( + "Unable to fetch `SourceRootInput` with `SourceRootId` ({:?}); this is a bug", + source_root_id + ), + }; *source_root } @@ -121,10 +129,13 @@ impl Files { } pub fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput { - let file_source_root = self - .file_source_roots - .get(&id) - .expect("Unable to fetch FileSourceRootInput; this is a bug"); + let file_source_root = match self.file_source_roots.get(&id) { + Some(file_source_root) => file_source_root, + None => panic!( + "Unable to get `FileSourceRootInput` with `vfs::FileId` ({:?}); this is a bug", + id + ), + }; *file_source_root } From ea6844560a0c281e52b16d8f8e3cf6e5463434dc Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 28 Apr 2025 20:14:58 -0400 Subject: [PATCH 033/262] Move `in_external_macro` to `SyntaxContext` --- compiler/rustc_span/src/hygiene.rs | 25 +++++++++++++++++++++++++ compiler/rustc_span/src/lib.rs | 21 +++------------------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index ab0a802dc7f7..b621920d62ba 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -41,6 +41,7 @@ use tracing::{debug, trace}; use crate::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, StableCrateId}; use crate::edition::Edition; +use crate::source_map::SourceMap; use crate::symbol::{Symbol, kw, sym}; use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals}; @@ -907,6 +908,30 @@ impl SyntaxContext { pub fn edition(self) -> Edition { HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition) } + + /// Returns whether this context originates in a foreign crate's external macro. + /// + /// This is used to test whether a lint should not even begin to figure out whether it should + /// be reported on the current node. + pub fn in_external_macro(self, sm: &SourceMap) -> bool { + let expn_data = self.outer_expn_data(); + match expn_data.kind { + ExpnKind::Root + | ExpnKind::Desugaring( + DesugaringKind::ForLoop + | DesugaringKind::WhileLoop + | DesugaringKind::OpaqueTy + | DesugaringKind::Async + | DesugaringKind::Await, + ) => false, + ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" + ExpnKind::Macro(MacroKind::Bang, _) => { + // Dummy span for the `def_site` means it's an external macro. + expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site) + } + ExpnKind::Macro { .. } => true, // definitely a plugin + } + } } impl fmt::Debug for SyntaxContext { diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index fccdaed21a20..79aede72a293 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -607,28 +607,13 @@ impl Span { !self.is_dummy() && sm.is_span_accessible(self) } - /// Returns whether `span` originates in a foreign crate's external macro. + /// Returns whether this span originates in a foreign crate's external macro. /// /// This is used to test whether a lint should not even begin to figure out whether it should /// be reported on the current node. + #[inline] pub fn in_external_macro(self, sm: &SourceMap) -> bool { - let expn_data = self.ctxt().outer_expn_data(); - match expn_data.kind { - ExpnKind::Root - | ExpnKind::Desugaring( - DesugaringKind::ForLoop - | DesugaringKind::WhileLoop - | DesugaringKind::OpaqueTy - | DesugaringKind::Async - | DesugaringKind::Await, - ) => false, - ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" - ExpnKind::Macro(MacroKind::Bang, _) => { - // Dummy span for the `def_site` means it's an external macro. - expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site) - } - ExpnKind::Macro { .. } => true, // definitely a plugin - } + self.ctxt().in_external_macro(sm) } /// Returns `true` if `span` originates in a derive-macro's expansion. From d93d553a0ce1dde45fa5cebd111d41aa9c767d09 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 29 Apr 2025 10:40:06 +0200 Subject: [PATCH 034/262] refactor: Clean up cache priming cancellation handling --- .../rust-analyzer/crates/hir/src/symbols.rs | 17 +++---- .../rust-analyzer/crates/ide-db/src/lib.rs | 10 +--- .../crates/ide-db/src/prime_caches.rs | 51 ++++++++++++++----- src/tools/rust-analyzer/crates/ide/src/lib.rs | 4 +- .../rust-analyzer/src/cli/analysis_stats.rs | 3 +- .../crates/rust-analyzer/src/discover.rs | 6 +-- .../rust-analyzer/crates/stdx/src/thread.rs | 2 + 7 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 3d944afb8b30..e87ab87407ff 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -13,13 +13,13 @@ use hir_def::{ use hir_expand::{HirFileId, name::Name}; use hir_ty::{ db::HirDatabase, - display::{DisplayTarget, HirDisplay, hir_display_with_store}, + display::{HirDisplay, hir_display_with_store}, }; use intern::Symbol; use rustc_hash::FxHashMap; use syntax::{AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName}; -use crate::{Module, ModuleDef, Semantics}; +use crate::{HasCrate, Module, ModuleDef, Semantics}; pub type FxIndexSet = indexmap::IndexSet>; @@ -66,7 +66,6 @@ pub struct SymbolCollector<'a> { symbols: FxIndexSet, work: Vec, current_container_name: Option, - display_target: DisplayTarget, } /// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect @@ -78,10 +77,6 @@ impl<'a> SymbolCollector<'a> { symbols: Default::default(), work: Default::default(), current_container_name: None, - display_target: DisplayTarget::from_crate( - db, - *db.all_crates().last().expect("no crate graph present"), - ), } } @@ -93,8 +88,7 @@ impl<'a> SymbolCollector<'a> { pub fn collect(&mut self, module: Module) { let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered(); - tracing::info!(?module, "SymbolCollector::collect",); - self.display_target = module.krate().to_display_target(self.db); + tracing::info!(?module, "SymbolCollector::collect"); // The initial work is the root module we're collecting, additional work will // be populated as we traverse the module's definitions. @@ -321,7 +315,10 @@ impl<'a> SymbolCollector<'a> { let impl_data = self.db.impl_signature(impl_id); let impl_name = Some( hir_display_with_store(impl_data.self_ty, &impl_data.store) - .display(self.db, self.display_target) + .display( + self.db, + crate::Impl::from(impl_id).krate(self.db).to_display_target(self.db), + ) .to_smolstr(), ); self.with_container_name(impl_name, |s| { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index d3934e14abf9..a433f184e765 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -78,6 +78,8 @@ pub type FileRange = FileRangeWrapper; #[salsa::db] pub struct RootDatabase { + // FIXME: Revisit this commit now that we migrated to the new salsa, given we store arcs in this + // db directly now // We use `ManuallyDrop` here because every codegen unit that contains a // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable, // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes @@ -234,14 +236,6 @@ impl RootDatabase { // ); // hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048); } - - pub fn snapshot(&self) -> Self { - Self { - storage: self.storage.clone(), - files: self.files.clone(), - crates_map: self.crates_map.clone(), - } - } } #[query_group::query_group] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 17c3f75ce173..5e8d016bfb02 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -51,6 +51,7 @@ pub fn parallel_prime_caches( enum ParallelPrimeCacheWorkerProgress { BeginCrate { crate_id: Crate, crate_name: Symbol }, EndCrate { crate_id: Crate }, + Cancelled(Cancelled), } // We split off def map computation from other work, @@ -71,26 +72,32 @@ pub fn parallel_prime_caches( progress_sender .send(ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name })?; - match kind { + let cancelled = Cancelled::catch(|| match kind { PrimingPhase::DefMap => _ = db.crate_def_map(crate_id), PrimingPhase::ImportMap => _ = db.import_map(crate_id), PrimingPhase::CrateSymbols => _ = db.crate_symbols(crate_id.into()), - } + }); - progress_sender.send(ParallelPrimeCacheWorkerProgress::EndCrate { crate_id })?; + match cancelled { + Ok(()) => progress_sender + .send(ParallelPrimeCacheWorkerProgress::EndCrate { crate_id })?, + Err(cancelled) => progress_sender + .send(ParallelPrimeCacheWorkerProgress::Cancelled(cancelled))?, + } } Ok::<_, crossbeam_channel::SendError<_>>(()) }; for id in 0..num_worker_threads { - let worker = prime_caches_worker.clone(); - let db = db.snapshot(); - stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) .allow_leak(true) .name(format!("PrimeCaches#{id}")) - .spawn(move || Cancelled::catch(|| worker(db.snapshot()))) + .spawn({ + let worker = prime_caches_worker.clone(); + let db = db.clone(); + move || worker(db) + }) .expect("failed to spawn thread"); } @@ -142,9 +149,14 @@ pub fn parallel_prime_caches( continue; } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { - // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_revision_cancelled(); - break; + // all our workers have exited, mark us as finished and exit + cb(ParallelPrimeCachesProgress { + crates_currently_indexing: vec![], + crates_done, + crates_total: crates_done, + work_type: "Indexing", + }); + return; } }; match worker_progress { @@ -156,6 +168,10 @@ pub fn parallel_prime_caches( crates_to_prime.mark_done(crate_id); crates_done += 1; } + ParallelPrimeCacheWorkerProgress::Cancelled(cancelled) => { + // Cancelled::throw should probably be public + std::panic::resume_unwind(Box::new(cancelled)); + } }; let progress = ParallelPrimeCachesProgress { @@ -186,9 +202,14 @@ pub fn parallel_prime_caches( continue; } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { - // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_revision_cancelled(); - break; + // all our workers have exited, mark us as finished and exit + cb(ParallelPrimeCachesProgress { + crates_currently_indexing: vec![], + crates_done, + crates_total: crates_done, + work_type: "Populating symbols", + }); + return; } }; match worker_progress { @@ -199,6 +220,10 @@ pub fn parallel_prime_caches( crates_currently_indexing.swap_remove(&crate_id); crates_done += 1; } + ParallelPrimeCacheWorkerProgress::Cancelled(cancelled) => { + // Cancelled::throw should probably be public + std::panic::resume_unwind(Box::new(cancelled)); + } }; let progress = ParallelPrimeCachesProgress { diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index e7f5fcbf69f3..aa525a86123d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -182,7 +182,7 @@ impl AnalysisHost { /// Returns a snapshot of the current state, which you can query for /// semantic information. pub fn analysis(&self) -> Analysis { - Analysis { db: self.db.snapshot() } + Analysis { db: self.db.clone() } } /// Applies changes to the current state of the world. If there are @@ -864,7 +864,7 @@ impl Analysis { where F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, { - let snap = self.db.snapshot(); + let snap = self.db.clone(); Cancelled::catch(|| f(&snap)) } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index c50df4b6d45e..a1e4adf0844a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -701,10 +701,9 @@ impl flags::AnalysisStats { if self.parallel { let mut inference_sw = self.stop_watch(); - let snap = db.snapshot(); bodies .par_iter() - .map_with(snap, |snap, &body| { + .map_with(db.clone(), |snap, &body| { snap.body(body.into()); snap.infer(body.into()); }) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs index 67ddc41f3b21..24c433610f1a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs @@ -126,10 +126,8 @@ impl CargoParser for DiscoverProjectParser { Some(msg) } Err(err) => { - let err = DiscoverProjectData::Error { - error: format!("{:#?}\n{}", err, line), - source: None, - }; + let err = + DiscoverProjectData::Error { error: format!("{err:#?}\n{line}"), source: None }; Some(DiscoverProjectMessage::new(err)) } } diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread.rs b/src/tools/rust-analyzer/crates/stdx/src/thread.rs index 6c742fecf1b6..3d1453831269 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/thread.rs @@ -56,6 +56,8 @@ impl Builder { Self { inner: self.inner.stack_size(size), ..self } } + /// Whether dropping should detach the thread + /// instead of joining it. #[must_use] pub fn allow_leak(self, allow_leak: bool) -> Self { Self { allow_leak, ..self } From 9f4abd313dfe3fbb0984d79a4a232009c582e9f5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 19 Feb 2025 17:47:48 +0100 Subject: [PATCH 035/262] stabilize ptr::swap_nonoverlapping in const --- library/core/src/intrinsics/mod.rs | 1 - library/core/src/ptr/mod.rs | 37 ++++++++++++++++++- library/coretests/tests/lib.rs | 1 - library/coretests/tests/ptr.rs | 4 ++ tests/ui/consts/missing_span_in_backtrace.rs | 2 - .../consts/missing_span_in_backtrace.stderr | 12 +++--- 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c5d5bc000f1c..5649736e4049 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3320,7 +3320,6 @@ pub const fn is_val_statically_known(_arg: T) -> bool { #[inline] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] -#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic pub const unsafe fn typed_swap_nonoverlapping(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 445c789a7de2..aa103af93ffc 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1065,10 +1065,45 @@ pub const unsafe fn swap(x: *mut T, y: *mut T) { /// assert_eq!(x, [7, 8, 3, 4]); /// assert_eq!(y, [1, 2, 9]); /// ``` +/// +/// # Const evaluation limitations +/// +/// If this function is invoked during const-evaluation, the current implementation has a small (and +/// rarely relevant) limitation: if `count` is at least 2 and the data pointed to by `x` or `y` +/// contains a pointer that crosses the boundary of two `T`-sized chunks of memory, the function may +/// fail to evaluate (similar to a panic during const-evaluation). This behavior may change in the +/// future. +/// +/// The limitation is illustrated by the following example: +/// +/// ``` +/// use std::mem::size_of; +/// use std::ptr; +/// +/// const { unsafe { +/// const PTR_SIZE: usize = size_of::<*const i32>(); +/// let mut data1 = [0u8; PTR_SIZE]; +/// let mut data2 = [0u8; PTR_SIZE]; +/// // Store a pointer in `data1`. +/// data1.as_mut_ptr().cast::<*const i32>().write_unaligned(&42); +/// // Swap the contents of `data1` and `data2` by swapping `PTR_SIZE` many `u8`-sized chunks. +/// // This call will fail, because the pointer in `data1` crosses the boundary +/// // between several of the 1-byte chunks that are being swapped here. +/// //ptr::swap_nonoverlapping(data1.as_mut_ptr(), data2.as_mut_ptr(), PTR_SIZE); +/// // Swap the contents of `data1` and `data2` by swapping a single chunk of size +/// // `[u8; PTR_SIZE]`. That works, as there is no pointer crossing the boundary between +/// // two chunks. +/// ptr::swap_nonoverlapping(&mut data1, &mut data2, 1); +/// // Read the pointer from `data2` and dereference it. +/// let ptr = data2.as_ptr().cast::<*const i32>().read_unaligned(); +/// assert!(*ptr == 42); +/// } } +/// ``` #[inline] #[stable(feature = "swap_nonoverlapping", since = "1.27.0")] -#[rustc_const_unstable(feature = "const_swap_nonoverlapping", issue = "133668")] +#[rustc_const_stable(feature = "const_swap_nonoverlapping", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "ptr_swap_nonoverlapping"] +#[rustc_allow_const_fn_unstable(const_eval_select)] // both implementations behave the same pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { ub_checks::assert_unsafe_precondition!( check_library_ub, diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index ef548971aafa..195fe3890dbc 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -15,7 +15,6 @@ #![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(const_eval_select)] -#![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(core_intrinsics_fallbacks)] diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 7d6e4eac1e21..bb60fb07468f 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -949,6 +949,10 @@ fn test_const_swap_ptr() { // Make sure they still work. assert!(*s1.0.ptr == 1); assert!(*s2.0.ptr == 666); + + // This is where we'd swap again using a `u8` type and a `count` of `size_of::()` if it + // were not for the limitation of `swap_nonoverlapping` around pointers crossing multiple + // elements. }; } diff --git a/tests/ui/consts/missing_span_in_backtrace.rs b/tests/ui/consts/missing_span_in_backtrace.rs index c8c7453daa12..490eb57c24d4 100644 --- a/tests/ui/consts/missing_span_in_backtrace.rs +++ b/tests/ui/consts/missing_span_in_backtrace.rs @@ -1,7 +1,5 @@ //@ compile-flags: -Z ui-testing=no - -#![feature(const_swap_nonoverlapping)] use std::{ mem::{self, MaybeUninit}, ptr, diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr index aad3d76dd269..88b3e37bb84f 100644 --- a/tests/ui/consts/missing_span_in_backtrace.stderr +++ b/tests/ui/consts/missing_span_in_backtrace.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/missing_span_in_backtrace.rs:16:9 + --> $DIR/missing_span_in_backtrace.rs:14:9 | -16 | / ptr::swap_nonoverlapping( -17 | | &mut ptr1 as *mut _ as *mut MaybeUninit, -18 | | &mut ptr2 as *mut _ as *mut MaybeUninit, -19 | | mem::size_of::<&i32>(), -20 | | ); +14 | / ptr::swap_nonoverlapping( +15 | | &mut ptr1 as *mut _ as *mut MaybeUninit, +16 | | &mut ptr2 as *mut _ as *mut MaybeUninit, +17 | | mem::size_of::<&i32>(), +18 | | ); | |_________^ unable to copy parts of a pointer from memory at ALLOC0 | note: inside `swap_nonoverlapping::>` From 97f0f68769f424b9149fc52225eb6fecaefe7808 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 29 Apr 2025 10:49:41 +0200 Subject: [PATCH 036/262] Cleanup cfg check handling in expression store lowering --- .../rust-analyzer/crates/hir-def/src/attr.rs | 55 ++++-- .../crates/hir-def/src/expr_store/expander.rs | 18 +- .../crates/hir-def/src/expr_store/lower.rs | 93 ++++++----- .../hir-def/src/expr_store/lower/generics.rs | 2 +- .../crates/hir-def/src/item_tree.rs | 4 +- .../crates/hir-expand/src/attrs.rs | 158 +++++++++++------- .../crates/hir-expand/src/declarative.rs | 2 +- .../crates/ide-db/src/prime_caches.rs | 20 ++- .../crates/rust-analyzer/src/bin/main.rs | 6 +- .../rust-analyzer/src/cli/diagnostics.rs | 12 +- .../src/cli/unresolved_references.rs | 12 +- .../crates/rust-analyzer/src/command.rs | 8 +- .../crates/rust-analyzer/src/flycheck.rs | 8 +- .../rust-analyzer/tests/slow-tests/support.rs | 3 +- .../rust-analyzer/crates/stdx/src/thread.rs | 13 +- .../crates/stdx/src/thread/pool.rs | 5 +- .../crates/vfs-notify/src/lib.rs | 3 +- 17 files changed, 234 insertions(+), 188 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index a80313aba3e4..bb6222b1d464 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -1,6 +1,6 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. -use std::{borrow::Cow, hash::Hash, ops}; +use std::{borrow::Cow, convert::identity, hash::Hash, ops}; use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; @@ -8,6 +8,7 @@ use either::Either; use hir_expand::{ HirFileId, InFile, attrs::{Attr, AttrId, RawAttrs, collect_attrs}, + span_map::SpanMapRef, }; use intern::{Symbol, sym}; use la_arena::{ArenaMap, Idx, RawIdx}; @@ -45,8 +46,27 @@ impl Attrs { (**self).iter().find(|attr| attr.id == id) } - pub(crate) fn filter(db: &dyn DefDatabase, krate: Crate, raw_attrs: RawAttrs) -> Attrs { - Attrs(raw_attrs.filter(db, krate)) + pub(crate) fn expand_cfg_attr( + db: &dyn DefDatabase, + krate: Crate, + raw_attrs: RawAttrs, + ) -> Attrs { + Attrs(raw_attrs.expand_cfg_attr(db, krate)) + } + + pub(crate) fn is_cfg_enabled_for( + db: &dyn DefDatabase, + owner: &dyn ast::HasAttrs, + span_map: SpanMapRef<'_>, + cfg_options: &CfgOptions, + ) -> Result<(), CfgExpr> { + RawAttrs::attrs_iter_expanded::(db, owner, span_map, cfg_options) + .filter_map(|attr| attr.cfg()) + .find_map(|cfg| match cfg_options.check(&cfg).is_none_or(identity) { + true => None, + false => Some(cfg), + }) + .map_or(Ok(()), Err) } } @@ -522,38 +542,41 @@ impl AttrsWithOwner { GenericParamId::ConstParamId(it) => { let src = it.parent().child_source(db); // FIXME: We should be never getting `None` here. - match src.value.get(it.local_id()) { - Some(val) => RawAttrs::from_attrs_owner( + return Attrs(match src.value.get(it.local_id()) { + Some(val) => RawAttrs::new_expanded( db, - src.with_value(val), + val, db.span_map(src.file_id).as_ref(), + def.krate(db).cfg_options(db), ), None => RawAttrs::EMPTY, - } + }); } GenericParamId::TypeParamId(it) => { let src = it.parent().child_source(db); // FIXME: We should be never getting `None` here. - match src.value.get(it.local_id()) { - Some(val) => RawAttrs::from_attrs_owner( + return Attrs(match src.value.get(it.local_id()) { + Some(val) => RawAttrs::new_expanded( db, - src.with_value(val), + val, db.span_map(src.file_id).as_ref(), + def.krate(db).cfg_options(db), ), None => RawAttrs::EMPTY, - } + }); } GenericParamId::LifetimeParamId(it) => { let src = it.parent.child_source(db); // FIXME: We should be never getting `None` here. - match src.value.get(it.local_id) { - Some(val) => RawAttrs::from_attrs_owner( + return Attrs(match src.value.get(it.local_id) { + Some(val) => RawAttrs::new_expanded( db, - src.with_value(val), + val, db.span_map(src.file_id).as_ref(), + def.krate(db).cfg_options(db), ), None => RawAttrs::EMPTY, - } + }); } }, AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it), @@ -561,7 +584,7 @@ impl AttrsWithOwner { AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it), }; - let attrs = raw_attrs.filter(db, def.krate(db)); + let attrs = raw_attrs.expand_cfg_attr(db, def.krate(db)); Attrs(attrs) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs index 7eec913dd654..d24f4b7028d7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs @@ -3,10 +3,11 @@ use std::mem; use base_db::Crate; +use cfg::CfgOptions; use drop_bomb::DropBomb; use hir_expand::{ ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId, - attrs::RawAttrs, eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap, + eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap, }; use span::{AstIdMap, Edition, SyntaxContext}; use syntax::ast::HasAttrs; @@ -64,22 +65,13 @@ impl Expander { } } - pub(super) fn attrs( - &self, - db: &dyn DefDatabase, - krate: Crate, - has_attrs: &dyn HasAttrs, - ) -> Attrs { - Attrs::filter(db, krate, RawAttrs::new(db, has_attrs, self.span_map.as_ref())) - } - pub(super) fn is_cfg_enabled( &self, db: &dyn DefDatabase, - krate: Crate, has_attrs: &dyn HasAttrs, - ) -> bool { - self.attrs(db, krate, has_attrs).is_cfg_enabled(krate.cfg_options(db)) + cfg_options: &CfgOptions, + ) -> Result<(), cfg::CfgExpr> { + Attrs::is_cfg_enabled_for(db, has_attrs, self.span_map.as_ref(), cfg_options) } pub(super) fn call_syntax_ctx(&self) -> SyntaxContext { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 7f907fdba8e3..50505d54ba2f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -7,6 +7,7 @@ mod path; use std::mem; +use cfg::CfgOptions; use either::Either; use hir_expand::{ HirFileId, InFile, Lookup, MacroDefId, @@ -81,8 +82,6 @@ pub(super) fn lower_body( // even though they should be the same. Also, when the body comes from multiple expansions, their // hygiene is different. - let krate = module.krate(); - let mut self_param = None; let mut source_map_self_param = None; let mut params = vec![]; @@ -100,9 +99,8 @@ pub(super) fn lower_body( // and skip the body. if skip_body { if let Some(param_list) = parameters { - if let Some(self_param_syn) = param_list - .self_param() - .filter(|self_param| collector.expander.is_cfg_enabled(db, krate, self_param)) + if let Some(self_param_syn) = + param_list.self_param().filter(|self_param| collector.check_cfg(self_param)) { let is_mutable = self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none(); @@ -119,10 +117,7 @@ pub(super) fn lower_body( source_map_self_param = Some(collector.expander.in_file(AstPtr::new(&self_param_syn))); } - let count = param_list - .params() - .filter(|it| collector.expander.is_cfg_enabled(db, krate, it)) - .count(); + let count = param_list.params().filter(|it| collector.check_cfg(it)).count(); params = (0..count).map(|_| collector.missing_pat()).collect(); }; let body_expr = collector.missing_expr(); @@ -138,9 +133,7 @@ pub(super) fn lower_body( } if let Some(param_list) = parameters { - if let Some(self_param_syn) = - param_list.self_param().filter(|it| collector.expander.is_cfg_enabled(db, krate, it)) - { + if let Some(self_param_syn) = param_list.self_param().filter(|it| collector.check_cfg(it)) { let is_mutable = self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none(); let hygiene = self_param_syn @@ -157,7 +150,7 @@ pub(super) fn lower_body( } for param in param_list.params() { - if collector.expander.is_cfg_enabled(db, krate, ¶m) { + if collector.check_cfg(¶m) { let param_pat = collector.collect_pat_top(param.pat()); params.push(param_pat); } @@ -346,7 +339,7 @@ pub(crate) fn lower_function( collector.collect_impl_trait(&mut expr_collector, |collector, mut impl_trait_lower_fn| { if let Some(param_list) = fn_.value.param_list() { if let Some(param) = param_list.self_param() { - let enabled = collector.expander.is_cfg_enabled(db, module.krate(), ¶m); + let enabled = collector.check_cfg(¶m); if enabled { has_self_param = true; params.push(match param.ty() { @@ -381,7 +374,7 @@ pub(crate) fn lower_function( } let p = param_list .params() - .filter(|param| collector.expander.is_cfg_enabled(db, module.krate(), param)) + .filter(|param| collector.check_cfg(param)) .filter(|param| { let is_variadic = param.dotdotdot_token().is_some(); has_variadic |= is_variadic; @@ -441,6 +434,7 @@ pub(crate) fn lower_function( pub struct ExprCollector<'db> { db: &'db dyn DefDatabase, + cfg_options: &'db CfgOptions, expander: Expander, def_map: Arc, local_def_map: Arc, @@ -553,6 +547,7 @@ impl ExprCollector<'_> { let expander = Expander::new(db, current_file_id, &def_map); ExprCollector { db, + cfg_options: module.krate().cfg_options(db), module, def_map, local_def_map, @@ -1026,7 +1021,9 @@ impl ExprCollector<'_> { /// Returns `None` if and only if the expression is `#[cfg]`d out. fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option { let syntax_ptr = AstPtr::new(&expr); - self.check_cfg(&expr)?; + if !self.check_cfg(&expr) { + return None; + } // FIXME: Move some of these arms out into separate methods for clarity Some(match expr { @@ -1114,6 +1111,7 @@ impl ExprCollector<'_> { ast::Expr::WhileExpr(e) => self.collect_while_loop(syntax_ptr, e), ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e), ast::Expr::CallExpr(e) => { + // FIXME: Remove this once we drop support for <1.86, https://github.com/rust-lang/rust/commit/ac9cb908ac4301dfc25e7a2edee574320022ae2c let is_rustc_box = { let attrs = e.attrs(); attrs.filter_map(|it| it.as_simple_atom()).any(|it| it == "rustc_box") @@ -1156,13 +1154,17 @@ impl ExprCollector<'_> { match_arm_list .arms() .filter_map(|arm| { - self.check_cfg(&arm).map(|()| MatchArm { - pat: self.collect_pat_top(arm.pat()), - expr: self.collect_expr_opt(arm.expr()), - guard: arm - .guard() - .map(|guard| self.collect_expr_opt(guard.condition())), - }) + if self.check_cfg(&arm) { + Some(MatchArm { + pat: self.collect_pat_top(arm.pat()), + expr: self.collect_expr_opt(arm.expr()), + guard: arm + .guard() + .map(|guard| self.collect_expr_opt(guard.condition())), + }) + } else { + None + } }) .collect() } else { @@ -1230,7 +1232,9 @@ impl ExprCollector<'_> { let fields = nfl .fields() .filter_map(|field| { - self.check_cfg(&field)?; + if !self.check_cfg(&field) { + return None; + } let name = field.field_name()?.as_name(); @@ -1483,7 +1487,9 @@ impl ExprCollector<'_> { } fn maybe_collect_expr_as_pat(&mut self, expr: &ast::Expr) -> Option { - self.check_cfg(expr)?; + if !self.check_cfg(expr) { + return None; + } let syntax_ptr = AstPtr::new(expr); let result = match expr { @@ -1558,7 +1564,9 @@ impl ExprCollector<'_> { let args = record_field_list .fields() .filter_map(|f| { - self.check_cfg(&f)?; + if !self.check_cfg(&f) { + return None; + } let field_expr = f.expr()?; let pat = self.collect_expr_as_pat(field_expr); let name = f.field_name()?.as_name(); @@ -2044,7 +2052,7 @@ impl ExprCollector<'_> { fn collect_stmt(&mut self, statements: &mut Vec, s: ast::Stmt) { match s { ast::Stmt::LetStmt(stmt) => { - if self.check_cfg(&stmt).is_none() { + if !self.check_cfg(&stmt) { return; } let pat = self.collect_pat_top(stmt.pat()); @@ -2059,7 +2067,7 @@ impl ExprCollector<'_> { ast::Stmt::ExprStmt(stmt) => { let expr = stmt.expr(); match &expr { - Some(expr) if self.check_cfg(expr).is_none() => return, + Some(expr) if !self.check_cfg(expr) => return, _ => (), } let has_semi = stmt.semicolon_token().is_some(); @@ -2074,7 +2082,7 @@ impl ExprCollector<'_> { } } ast::Stmt::Item(ast::Item::MacroDef(macro_)) => { - if self.check_cfg(¯o_).is_none() { + if !self.check_cfg(¯o_) { return; } let Some(name) = macro_.name() else { @@ -2086,7 +2094,7 @@ impl ExprCollector<'_> { self.collect_macro_def(statements, macro_id); } ast::Stmt::Item(ast::Item::MacroRules(macro_)) => { - if self.check_cfg(¯o_).is_none() { + if !self.check_cfg(¯o_) { return; } let Some(name) = macro_.name() else { @@ -2360,7 +2368,9 @@ impl ExprCollector<'_> { let args = record_pat_field_list .fields() .filter_map(|f| { - self.check_cfg(&f)?; + if !self.check_cfg(&f) { + return None; + } let ast_pat = f.pat()?; let pat = self.collect_pat(ast_pat, binding_list); let name = f.field_name()?.as_name(); @@ -2536,25 +2546,18 @@ impl ExprCollector<'_> { /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when /// not. - fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> Option<()> { - let attrs = self.expander.attrs(self.db, self.module.krate(), owner); - match attrs.cfg() { - Some(cfg) => { - let cfg_options = self.module.krate().cfg_options(self.db); - - if cfg_options.check(&cfg) != Some(false) { - return Some(()); - } - + fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> bool { + let enabled = self.expander.is_cfg_enabled(self.db, owner, self.cfg_options); + match enabled { + Ok(()) => true, + Err(cfg) => { self.source_map.diagnostics.push(ExpressionStoreDiagnostics::InactiveCode { node: self.expander.in_file(SyntaxNodePtr::new(owner.syntax())), cfg, - opts: cfg_options.clone(), + opts: self.cfg_options.clone(), }); - - None + false } - None => Some(()), } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs index 9485e703d9cb..42c85571f646 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs @@ -110,7 +110,7 @@ impl GenericParamsCollector { fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericParamList) { for generic_param in params.generic_params() { - let enabled = ec.expander.is_cfg_enabled(ec.db, ec.module.krate(), &generic_param); + let enabled = ec.check_cfg(&generic_param); if !enabled { continue; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 01d340cea6df..1b97eb72b6f2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -179,7 +179,7 @@ impl ItemTree { /// Returns the inner attributes of the source file. pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs { - Attrs::filter( + Attrs::expand_cfg_attr( db, krate, self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone(), @@ -191,7 +191,7 @@ impl ItemTree { } pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs { - Attrs::filter(db, krate, self.raw_attrs(of).clone()) + Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone()) } /// Returns a count of a few, expensive items. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 5dae27f7a16c..107316239809 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, fmt, ops}; use base_db::Crate; -use cfg::CfgExpr; +use cfg::{CfgExpr, CfgOptions}; use either::Either; use intern::{Interned, Symbol, sym}; @@ -14,11 +14,10 @@ use syntax::{AstNode, AstToken, SyntaxNode, ast, match_ast}; use syntax_bridge::{DocCommentDesugarMode, desugar_doc_comment_text, syntax_node_to_token_tree}; use triomphe::ThinArc; -use crate::name::Name; use crate::{ - InFile, db::ExpandDatabase, mod_path::ModPath, + name::Name, span_map::SpanMapRef, tt::{self, TopSubtree, token_to_literal}, }; @@ -49,29 +48,7 @@ impl RawAttrs { owner: &dyn ast::HasAttrs, span_map: SpanMapRef<'_>, ) -> Self { - let entries: Vec<_> = collect_attrs(owner) - .filter_map(|(id, attr)| match attr { - Either::Left(attr) => { - attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id)) - } - Either::Right(comment) => comment.doc_comment().map(|doc| { - let span = span_map.span_for_range(comment.syntax().text_range()); - let (text, kind) = - desugar_doc_comment_text(doc, DocCommentDesugarMode::ProcMacro); - Attr { - id, - input: Some(Box::new(AttrInput::Literal(tt::Literal { - symbol: text, - span, - kind, - suffix: None, - }))), - path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))), - ctxt: span.ctx, - } - }), - }) - .collect(); + let entries: Vec<_> = Self::attrs_iter::(db, owner, span_map).collect(); let entries = if entries.is_empty() { None @@ -82,12 +59,61 @@ impl RawAttrs { RawAttrs { entries } } - pub fn from_attrs_owner( + /// A [`RawAttrs`] that has its `#[cfg_attr(...)]` attributes expanded. + pub fn new_expanded( db: &dyn ExpandDatabase, - owner: InFile<&dyn ast::HasAttrs>, + owner: &dyn ast::HasAttrs, span_map: SpanMapRef<'_>, + cfg_options: &CfgOptions, ) -> Self { - Self::new(db, owner.value, span_map) + let entries: Vec<_> = + Self::attrs_iter_expanded::(db, owner, span_map, cfg_options).collect(); + + let entries = if entries.is_empty() { + None + } else { + Some(ThinArc::from_header_and_iter((), entries.into_iter())) + }; + + RawAttrs { entries } + } + + pub fn attrs_iter( + db: &dyn ExpandDatabase, + owner: &dyn ast::HasAttrs, + span_map: SpanMapRef<'_>, + ) -> impl Iterator { + collect_attrs(owner).filter_map(move |(id, attr)| match attr { + Either::Left(attr) => { + attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id)) + } + Either::Right(comment) if DESUGAR_COMMENTS => comment.doc_comment().map(|doc| { + let span = span_map.span_for_range(comment.syntax().text_range()); + let (text, kind) = desugar_doc_comment_text(doc, DocCommentDesugarMode::ProcMacro); + Attr { + id, + input: Some(Box::new(AttrInput::Literal(tt::Literal { + symbol: text, + span, + kind, + suffix: None, + }))), + path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))), + ctxt: span.ctx, + } + }), + Either::Right(_) => None, + }) + } + + pub fn attrs_iter_expanded( + db: &dyn ExpandDatabase, + owner: &dyn ast::HasAttrs, + span_map: SpanMapRef<'_>, + cfg_options: &CfgOptions, + ) -> impl Iterator { + Self::attrs_iter::(db, owner, span_map) + .flat_map(|attr| attr.expand_cfg_attr(db, cfg_options)) } pub fn merge(&self, other: Self) -> Self { @@ -114,9 +140,8 @@ impl RawAttrs { } } - /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. - // FIXME: This should return a different type, signaling it was filtered? - pub fn filter(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs { + /// Processes `cfg_attr`s + pub fn expand_cfg_attr(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs { let has_cfg_attrs = self.iter().any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr)); if !has_cfg_attrs { @@ -126,37 +151,8 @@ impl RawAttrs { let cfg_options = krate.cfg_options(db); let new_attrs = self .iter() - .flat_map(|attr| -> SmallVec<[_; 1]> { - let is_cfg_attr = attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr); - if !is_cfg_attr { - return smallvec![attr.clone()]; - } - - let subtree = match attr.token_tree_value() { - Some(it) => it, - _ => return smallvec![attr.clone()], - }; - - let (cfg, parts) = match parse_cfg_attr_input(subtree) { - Some(it) => it, - None => return smallvec![attr.clone()], - }; - let index = attr.id; - let attrs = parts - .enumerate() - .take(1 << AttrId::CFG_ATTR_BITS) - .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx))); - - let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg); - let cfg = CfgExpr::parse(&cfg); - if cfg_options.check(&cfg) == Some(false) { - smallvec![] - } else { - cov_mark::hit!(cfg_attr_active); - - attrs.collect() - } - }) + .cloned() + .flat_map(|attr| attr.expand_cfg_attr(db, cfg_options)) .collect::>(); let entries = if new_attrs.is_empty() { None @@ -316,6 +312,42 @@ impl Attr { pub fn path(&self) -> &ModPath { &self.path } + + pub fn expand_cfg_attr( + self, + db: &dyn ExpandDatabase, + cfg_options: &CfgOptions, + ) -> impl IntoIterator { + let is_cfg_attr = self.path.as_ident().is_some_and(|name| *name == sym::cfg_attr); + if !is_cfg_attr { + return smallvec![self.clone()]; + } + + let subtree = match self.token_tree_value() { + Some(it) => it, + _ => return smallvec![self.clone()], + }; + + let (cfg, parts) = match parse_cfg_attr_input(subtree) { + Some(it) => it, + None => return smallvec![self.clone()], + }; + let index = self.id; + let attrs = parts + .enumerate() + .take(1 << AttrId::CFG_ATTR_BITS) + .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx))); + + let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg); + let cfg = CfgExpr::parse(&cfg); + if cfg_options.check(&cfg) == Some(false) { + smallvec![] + } else { + cov_mark::hit!(cfg_attr_active); + + attrs.collect::>() + } + } } impl Attr { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index 1fa682ce3a2d..0d100c1364ab 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -82,7 +82,7 @@ impl DeclarativeMacroExpander { let transparency = |node| { // ... would be nice to have the item tree here - let attrs = RawAttrs::new(db, node, map.as_ref()).filter(db, def_crate); + let attrs = RawAttrs::new_expanded(db, node, map.as_ref(), def_crate.cfg_options(db)); match attrs .iter() .find(|it| { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 5e8d016bfb02..cbe31405ab78 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -90,15 +90,17 @@ pub fn parallel_prime_caches( }; for id in 0..num_worker_threads { - stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) - .allow_leak(true) - .name(format!("PrimeCaches#{id}")) - .spawn({ - let worker = prime_caches_worker.clone(); - let db = db.clone(); - move || worker(db) - }) - .expect("failed to spawn thread"); + stdx::thread::Builder::new( + stdx::thread::ThreadIntent::Worker, + format!("PrimeCaches#{id}"), + ) + .allow_leak(true) + .spawn({ + let worker = prime_caches_worker.clone(); + let db = db.clone(); + move || worker(db) + }) + .expect("failed to spawn thread"); } (work_sender, progress_receiver) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index ea5a5eaa6a44..4dba97c8ec49 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -182,10 +182,8 @@ fn with_extra_thread( thread_intent: stdx::thread::ThreadIntent, f: impl FnOnce() -> anyhow::Result<()> + Send + 'static, ) -> anyhow::Result<()> { - let handle = stdx::thread::Builder::new(thread_intent) - .name(thread_name.into()) - .stack_size(STACK_SIZE) - .spawn(f)?; + let handle = + stdx::thread::Builder::new(thread_intent, thread_name).stack_size(STACK_SIZE).spawn(f)?; handle.join()?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 7c4eeebdfa31..7b12cb14009f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -15,11 +15,13 @@ impl flags::Diagnostics { pub fn run(self) -> anyhow::Result<()> { const STACK_SIZE: usize = 1024 * 1024 * 8; - let handle = stdx::thread::Builder::new(stdx::thread::ThreadIntent::LatencySensitive) - .name("BIG_STACK_THREAD".into()) - .stack_size(STACK_SIZE) - .spawn(|| self.run_()) - .unwrap(); + let handle = stdx::thread::Builder::new( + stdx::thread::ThreadIntent::LatencySensitive, + "BIG_STACK_THREAD", + ) + .stack_size(STACK_SIZE) + .spawn(|| self.run_()) + .unwrap(); handle.join() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index bca7c8a098c2..1d4fbb942235 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -15,11 +15,13 @@ impl flags::UnresolvedReferences { pub fn run(self) -> anyhow::Result<()> { const STACK_SIZE: usize = 1024 * 1024 * 8; - let handle = stdx::thread::Builder::new(stdx::thread::ThreadIntent::LatencySensitive) - .name("BIG_STACK_THREAD".into()) - .stack_size(STACK_SIZE) - .spawn(|| self.run_()) - .unwrap(); + let handle = stdx::thread::Builder::new( + stdx::thread::ThreadIntent::LatencySensitive, + "BIG_STACK_THREAD", + ) + .stack_size(STACK_SIZE) + .spawn(|| self.run_()) + .unwrap(); handle.join() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs index 0035d941e2c6..d6c80c399ba2 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs @@ -148,10 +148,10 @@ impl CommandHandle { let stderr = child.0.stderr().take().unwrap(); let actor = CargoActor::::new(parser, sender, stdout, stderr); - let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) - .name("CommandHandle".to_owned()) - .spawn(move || actor.run()) - .expect("failed to spawn thread"); + let thread = + stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "CommandHandle") + .spawn(move || actor.run()) + .expect("failed to spawn thread"); Ok(CommandHandle { program, arguments, current_dir, child, thread, _phantom: PhantomData }) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 2778b311e1e3..fc312439d58c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -133,10 +133,10 @@ impl FlycheckHandle { let actor = FlycheckActor::new(id, sender, config, sysroot_root, workspace_root, manifest_path); let (sender, receiver) = unbounded::(); - let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) - .name("Flycheck".to_owned()) - .spawn(move || actor.run(receiver)) - .expect("failed to spawn thread"); + let thread = + stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, format!("Flycheck{id}")) + .spawn(move || actor.run(receiver)) + .expect("failed to spawn thread"); FlycheckHandle { id, sender, _thread: thread } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index 3f97952365f3..7b5a53311217 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -298,8 +298,7 @@ impl Server { ) -> Server { let (connection, client) = Connection::memory(); - let _thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) - .name("test server".to_owned()) + let _thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "test server") .spawn(move || main_loop(config, connection).unwrap()) .expect("failed to spawn a thread"); diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread.rs b/src/tools/rust-analyzer/crates/stdx/src/thread.rs index 3d1453831269..a34e9e4a6551 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/thread.rs @@ -26,12 +26,12 @@ pub use pool::Pool; /// # Panics /// /// Panics if failed to spawn the thread. -pub fn spawn(intent: ThreadIntent, f: F) -> JoinHandle +pub fn spawn(intent: ThreadIntent, name: String, f: F) -> JoinHandle where F: (FnOnce() -> T) + Send + 'static, T: Send + 'static, { - Builder::new(intent).spawn(f).expect("failed to spawn thread") + Builder::new(intent, name).spawn(f).expect("failed to spawn thread") } pub struct Builder { @@ -42,13 +42,8 @@ pub struct Builder { impl Builder { #[must_use] - pub fn new(intent: ThreadIntent) -> Self { - Self { intent, inner: jod_thread::Builder::new(), allow_leak: false } - } - - #[must_use] - pub fn name(self, name: String) -> Self { - Self { inner: self.inner.name(name), ..self } + pub fn new(intent: ThreadIntent, name: impl Into) -> Self { + Self { intent, inner: jod_thread::Builder::new().name(name.into()), allow_leak: false } } #[must_use] diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs index 074cd747dacc..a8de4db624f1 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs @@ -50,10 +50,9 @@ impl Pool { let extant_tasks = Arc::new(AtomicUsize::new(0)); let mut handles = Vec::with_capacity(threads); - for _ in 0..threads { - let handle = Builder::new(INITIAL_INTENT) + for idx in 0..threads { + let handle = Builder::new(INITIAL_INTENT, format!("Worker{idx}",)) .stack_size(STACK_SIZE) - .name("Worker".into()) .allow_leak(true) .spawn({ let extant_tasks = Arc::clone(&extant_tasks); diff --git a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs index e918fd0887db..a03337dbc51e 100644 --- a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs +++ b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs @@ -38,8 +38,7 @@ impl loader::Handle for NotifyHandle { fn spawn(sender: loader::Sender) -> NotifyHandle { let actor = NotifyActor::new(sender); let (sender, receiver) = unbounded::(); - let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) - .name("VfsLoader".to_owned()) + let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "VfsLoader") .spawn(move || actor.run(receiver)) .expect("failed to spawn thread"); NotifyHandle { sender, _thread: thread } From e561ec0e03c4991938e0d3d39766fa74d86f7448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 29 Apr 2025 12:59:15 +0200 Subject: [PATCH 037/262] Remove global `next_disambiguator` state and handle it with a `DisambiguatorState` type --- compiler/rustc_ast_lowering/src/lib.rs | 6 +- .../src/const_eval/dummy_machine.rs | 4 +- .../src/const_eval/machine.rs | 5 +- .../rustc_const_eval/src/interpret/intern.rs | 15 ++-- .../rustc_const_eval/src/interpret/util.rs | 5 +- compiler/rustc_hir/src/def.rs | 11 +-- compiler/rustc_hir/src/definitions.rs | 56 +++++++++++---- .../src/collect/resolve_bound_vars.rs | 30 +++++--- compiler/rustc_middle/src/ty/context.rs | 17 +++-- compiler/rustc_middle/src/ty/mod.rs | 3 + compiler/rustc_middle/src/ty/print/pretty.rs | 4 ++ .../src/coroutine/by_move_body.rs | 10 ++- compiler/rustc_resolve/src/lib.rs | 7 +- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 70 +++++++++++++------ tests/ui/delegation/unsupported.stderr | 8 +-- .../impl-trait/in-trait/doesnt-satisfy.stderr | 4 +- tests/ui/impl-trait/in-trait/dump.rs | 2 +- tests/ui/impl-trait/in-trait/dump.stderr | 2 +- ...atability-via-leakage-cycle.current.stderr | 4 +- ...ompatability-via-leakage-cycle.next.stderr | 8 +-- .../return-dont-satisfy-bounds.stderr | 4 +- .../issue-103052-2.stderr | 4 +- 24 files changed, 190 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b2a0b32fe261..e53f64805802 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -509,7 +509,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.hir_def_key(self.local_def_id(node_id)), ); - let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id(); + let def_id = self + .tcx + .at(span) + .create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator) + .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.resolver.node_id_to_def_id.insert(node_id, def_id); diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index 46dcebc46e9c..dc5f84adb76f 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -1,3 +1,5 @@ +use rustc_hir::def_id::LocalDefId; +use rustc_hir::definitions::DisambiguatorState; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult}; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; @@ -42,7 +44,7 @@ pub macro throw_machine_stop_str($($tt:tt)*) {{ pub struct DummyMachine; impl HasStaticRootDefId for DummyMachine { - fn static_def_id(&self) -> Option { + fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> { None } } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 61a7ec13511c..dddfc6a4e092 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -6,6 +6,7 @@ use rustc_abi::{Align, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem}; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; @@ -63,7 +64,7 @@ pub struct CompileTimeMachine<'tcx> { /// If `Some`, we are evaluating the initializer of the static with the given `LocalDefId`, /// storing the result in the given `AllocId`. /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops. - pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>, + pub(crate) static_root_ids: Option<(AllocId, LocalDefId, DisambiguatorState)>, /// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes). union_data_ranges: FxHashMap, RangeSet>, @@ -706,7 +707,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> { // Check if this is the currently evaluated static. - if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { + if Some(alloc_id) == ecx.machine.static_root_ids.as_ref().map(|(id, ..)| *id) { return Err(ConstEvalErrKind::RecursiveStatic).into(); } // If this is another static, make sure we fire off the query to detect cycles. diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 8f0cb197c445..adf2c255d089 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -17,6 +17,7 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; +use rustc_hir::definitions::DisambiguatorState; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult}; use rustc_middle::query::TyCtxtAt; @@ -46,12 +47,13 @@ pub trait CompileTimeMachine<'tcx, T> = Machine< pub trait HasStaticRootDefId { /// Returns the `DefId` of the static item that is currently being evaluated. /// Used for interning to be able to handle nested allocations. - fn static_def_id(&self) -> Option; + fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)>; } impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> { - fn static_def_id(&self) -> Option { - Some(self.static_root_ids?.1) + fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> { + let (_, static_id, d) = self.static_root_ids.as_mut()?; + Some((*static_id, d)) } } @@ -87,8 +89,8 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( } // link the alloc id to the actual allocation let alloc = ecx.tcx.mk_const_alloc(alloc); - if let Some(static_id) = ecx.machine.static_def_id() { - intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc); + if let Some((static_id, disambiguator)) = ecx.machine.static_parent_and_disambiguator() { + intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc, disambiguator); } else { ecx.tcx.set_alloc_id_memory(alloc_id, alloc); } @@ -102,11 +104,14 @@ fn intern_as_new_static<'tcx>( static_id: LocalDefId, alloc_id: AllocId, alloc: ConstAllocation<'tcx>, + disambiguator: &mut DisambiguatorState, ) { let feed = tcx.create_def( static_id, Some(sym::nested), DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, + None, + disambiguator, ); tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index ba579e25f036..faaa2bd24bbd 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,4 +1,5 @@ use rustc_hir::def_id::LocalDefId; +use rustc_hir::definitions::DisambiguatorState; use rustc_middle::mir; use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; @@ -40,8 +41,8 @@ pub(crate) fn create_static_alloc<'tcx>( ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit)?; let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into()); - assert_eq!(ecx.machine.static_root_ids, None); - ecx.machine.static_root_ids = Some((alloc_id, static_def_id)); + assert!(ecx.machine.static_root_ids.is_none()); + ecx.machine.static_root_ids = Some((alloc_id, static_def_id, DisambiguatorState::new())); assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none()); interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout)) } diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 9372ab532bf3..5872ec5aedf2 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -269,14 +269,9 @@ impl DefKind { | DefKind::TyParam | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()), - // An associated type name will be missing for an RPITIT. - DefKind::AssocTy => { - if let Some(name) = name { - DefPathData::TypeNs(name) - } else { - DefPathData::AnonAssocTy - } - } + // An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy), + // but those provide their own DefPathData. + DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()), // It's not exactly an anon const, but wrt DefPathData, there // is no difference. diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index bf7b1eefcf68..d66775cd20b0 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -68,7 +68,7 @@ impl DefPathTable { // // See the documentation for DefPathHash for more information. panic!( - "found DefPathHash collision between {def_path1:?} and {def_path2:?}. \ + "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \ Compilation cannot continue." ); } @@ -97,13 +97,31 @@ impl DefPathTable { } } +#[derive(Debug)] +pub struct DisambiguatorState { + next: UnordMap<(LocalDefId, DefPathData), u32>, +} + +impl DisambiguatorState { + pub fn new() -> Self { + Self { next: Default::default() } + } + + /// Creates a `DisambiguatorState` where the next allocated `(LocalDefId, DefPathData)` pair + /// will have `index` as the disambiguator. + pub fn with(def_id: LocalDefId, data: DefPathData, index: u32) -> Self { + let mut this = Self::new(); + this.next.insert((def_id, data), index); + this + } +} + /// The definition table containing node definitions. /// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s. /// It also stores mappings to convert `LocalDefId`s to/from `HirId`s. #[derive(Debug)] pub struct Definitions { table: DefPathTable, - next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>, } /// A unique identifier that we can use to lookup a definition @@ -173,7 +191,11 @@ impl DisambiguatedDefPathData { } } DefPathDataName::Anon { namespace } => { - write!(writer, "{{{}#{}}}", namespace, self.disambiguator) + if let DefPathData::AnonAssocTy(method) = self.data { + write!(writer, "{}::{{{}#{}}}", method, namespace, self.disambiguator) + } else { + write!(writer, "{{{}#{}}}", namespace, self.disambiguator) + } } } } @@ -288,7 +310,7 @@ pub enum DefPathData { /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name. OpaqueTy, /// An anonymous associated type from an RPITIT. - AnonAssocTy, + AnonAssocTy(Symbol), /// A synthetic body for a coroutine's by-move body. SyntheticCoroutineBody, } @@ -342,11 +364,20 @@ impl Definitions { let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) }; assert_eq!(root.local_def_index, CRATE_DEF_INDEX); - Definitions { table, next_disambiguator: Default::default() } + Definitions { table } } - /// Adds a definition with a parent definition. - pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId { + /// Creates a definition with a parent definition. + /// If there are multiple definitions with the same DefPathData and the same parent, use + /// `disambiguator` to differentiate them. Distinct `DisambiguatorState` instances are not + /// guaranteed to generate unique disambiguators and should instead ensure that the `parent` + /// and `data` pair is distinct from other instances. + pub fn create_def( + &mut self, + parent: LocalDefId, + data: DefPathData, + disambiguator: &mut DisambiguatorState, + ) -> LocalDefId { // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a // reference to `Definitions` and we're already holding a mutable reference. debug!( @@ -354,12 +385,12 @@ impl Definitions { self.def_path(parent).to_string_no_crate_verbose(), ); - // The root node must be created with `create_root_def()`. + // The root node must be created in `new()`. assert!(data != DefPathData::CrateRoot); // Find the next free disambiguator for this key. let disambiguator = { - let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0); + let next_disamb = disambiguator.next.entry((parent, data)).or_insert(0); let disambiguator = *next_disamb; *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); disambiguator @@ -411,7 +442,9 @@ impl DefPathData { pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), + TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => { + Some(name) + } Impl | ForeignMod @@ -422,7 +455,6 @@ impl DefPathData { | Ctor | AnonConst | OpaqueTy - | AnonAssocTy | SyntheticCoroutineBody => None, } } @@ -443,7 +475,7 @@ impl DefPathData { Ctor => DefPathDataName::Anon { namespace: sym::constructor }, AnonConst => DefPathDataName::Anon { namespace: sym::constant }, OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque }, - AnonAssocTy => DefPathDataName::Anon { namespace: sym::anon_assoc }, + AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc }, SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic }, } } 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 59ab36d98fda..104de262fee8 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -14,6 +14,7 @@ use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::definitions::DisambiguatorState; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node, @@ -63,6 +64,7 @@ impl ResolvedArg { struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, rbv: &'a mut ResolveBoundVars, + disambiguator: &'a mut DisambiguatorState, scope: ScopeRef<'a>, } @@ -245,8 +247,12 @@ pub(crate) fn provide(providers: &mut Providers) { #[instrument(level = "debug", skip(tcx))] fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars { let mut rbv = ResolveBoundVars::default(); - let mut visitor = - BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } }; + let mut visitor = BoundVarContext { + tcx, + rbv: &mut rbv, + scope: &Scope::Root { opt_parent_item: None }, + disambiguator: &mut DisambiguatorState::new(), + }; match tcx.hir_owner_node(local_def_id) { hir::OwnerNode::Item(item) => visitor.visit_item(item), hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), @@ -515,9 +521,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque); if capture_all_in_scope_lifetimes { + let tcx = self.tcx; let lifetime_ident = |def_id: LocalDefId| { - let name = self.tcx.item_name(def_id.to_def_id()); - let span = self.tcx.def_span(def_id); + let name = tcx.item_name(def_id.to_def_id()); + let span = tcx.def_span(def_id); Ident::new(name, span) }; @@ -1091,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, rbv, .. } = self; - let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope }; + let BoundVarContext { tcx, rbv, disambiguator, .. } = self; + let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); @@ -1446,7 +1453,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { #[instrument(level = "trace", skip(self, opaque_capture_scopes), ret)] fn remap_opaque_captures( - &self, + &mut self, opaque_capture_scopes: &Vec<(LocalDefId, &RefCell>)>, mut lifetime: ResolvedArg, ident: Ident, @@ -1462,8 +1469,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { for &(opaque_def_id, captures) in opaque_capture_scopes.iter().rev() { let mut captures = captures.borrow_mut(); let remapped = *captures.entry(lifetime).or_insert_with(|| { - let feed = - self.tcx.create_def(opaque_def_id, Some(ident.name), DefKind::LifetimeParam); + let feed = self.tcx.create_def( + opaque_def_id, + Some(ident.name), + DefKind::LifetimeParam, + None, + &mut self.disambiguator, + ); feed.def_span(ident.span); feed.def_ident_span(Some(ident.span)); feed.def_id() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e8dad1e056cb..fffbf0513482 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -34,7 +34,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::definitions::Definitions; +use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate}; @@ -1957,8 +1957,10 @@ impl<'tcx> TyCtxtAt<'tcx> { parent: LocalDefId, name: Option, def_kind: DefKind, + def_path_data: Option, + disambiguator: &mut DisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { - let feed = self.tcx.create_def(parent, name, def_kind); + let feed = self.tcx.create_def(parent, name, def_kind, def_path_data, disambiguator); feed.def_span(self.span); feed @@ -1972,8 +1974,10 @@ impl<'tcx> TyCtxt<'tcx> { parent: LocalDefId, name: Option, def_kind: DefKind, + def_path_data: Option, + disambiguator: &mut DisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { - let data = def_kind.def_path_data(name); + let data = def_path_data.unwrap_or_else(|| def_kind.def_path_data(name)); // The following call has the side effect of modifying the tables inside `definitions`. // These very tables are relied on by the incr. comp. engine to decode DepNodes and to // decode the on-disk cache. @@ -1983,12 +1987,7 @@ impl<'tcx> TyCtxt<'tcx> { // - has been created by this call to `create_def`. // As a consequence, this LocalDefId is always re-created before it is needed by the incr. // comp. engine itself. - // - // This call also writes to the value of the `source_span` query. - // This is fine because: - // - that query is `eval_always` so we won't miss its result changing; - // - this write will have happened before that query is called. - let def_id = self.untracked.definitions.write().create_def(parent, data); + let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator); // This function modifies `self.definitions` using a side-effect. // We need to ensure that these side effects are re-run by the incr. comp. engine. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index be00c0e116dd..4e4ef3f9bf2c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -38,6 +38,7 @@ use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; +use rustc_hir::definitions::DisambiguatorState; use rustc_index::IndexVec; use rustc_macros::{ Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, @@ -207,6 +208,8 @@ pub struct ResolverAstLowering { pub node_id_to_def_id: NodeMap, + pub disambiguator: DisambiguatorState, + pub trait_map: NodeMap>, /// List functions and methods for which lifetime elision was successful. pub lifetime_elision_allowed: FxHashSet, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1df3bff52442..f589c7df6285 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -391,6 +391,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let visible_parent_map = self.tcx().visible_parent_map(()); let kind = self.tcx().def_kind(def_id); + if let DefPathData::AnonAssocTy(..) = key.disambiguated_data.data { + return Ok(false); + } + let get_local_name = |this: &Self, name, def_id, key: DefKey| { if let Some(visible_parent) = visible_parent_map.get(&def_id) && let actual_parent = this.tcx().opt_parent(def_id) diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index dd0e07f2218e..bbc4531789b0 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -73,6 +73,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::definitions::DisambiguatorState; use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; @@ -213,8 +214,13 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( let mut by_move_body = body.clone(); MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body); - // This will always be `{closure#1}`, since the original coroutine is `{closure#0}`. - let body_def = tcx.create_def(parent_def_id, None, DefKind::SyntheticCoroutineBody); + let body_def = tcx.create_def( + parent_def_id, + None, + DefKind::SyntheticCoroutineBody, + None, + &mut DisambiguatorState::new(), + ); by_move_body.source = mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(())); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 4a252a7b5281..bb8d7b763719 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -55,6 +55,7 @@ use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS, }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; +use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; @@ -1184,6 +1185,8 @@ pub struct Resolver<'ra, 'tcx> { node_id_to_def_id: NodeMap>, + disambiguator: DisambiguatorState, + /// Indices of unnamed struct or variant fields with unresolved attributes. placeholder_field_indices: FxHashMap, /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` @@ -1347,7 +1350,7 @@ impl<'tcx> Resolver<'_, 'tcx> { ); // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()` - let feed = self.tcx.create_def(parent, name, def_kind); + let feed = self.tcx.create_def(parent, name, def_kind, None, &mut self.disambiguator); let def_id = feed.def_id(); // Create the definition. @@ -1561,6 +1564,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lint_buffer: LintBuffer::default(), next_node_id: CRATE_NODE_ID, node_id_to_def_id, + disambiguator: DisambiguatorState::new(), placeholder_field_indices: Default::default(), invocation_parents, legacy_const_generic_args: Default::default(), @@ -1690,6 +1694,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .into_items() .map(|(k, f)| (k, f.key())) .collect(), + disambiguator: self.disambiguator, trait_map: self.trait_map, lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 4b1b3903e403..ed32c34bb4b5 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -722,7 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { | hir::definitions::DefPathData::GlobalAsm | hir::definitions::DefPathData::MacroNs(..) | hir::definitions::DefPathData::LifetimeNs(..) - | hir::definitions::DefPathData::AnonAssocTy => { + | hir::definitions::DefPathData::AnonAssocTy(..) => { bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data); } }); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index f310aa655002..12aa876045c4 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -859,7 +859,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { | DefPathData::Impl | DefPathData::MacroNs(_) | DefPathData::LifetimeNs(_) - | DefPathData::AnonAssocTy => { + | DefPathData::AnonAssocTy(..) => { bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data) } }; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6cb9fdc6f931..f14a45aa1e3b 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; +use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, AmbigArg}; use rustc_middle::query::Providers; @@ -159,6 +160,22 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A container: ty::AssocItemContainer::Impl, } } +struct RPITVisitor { + rpits: FxIndexSet, +} + +impl<'tcx> Visitor<'tcx> for RPITVisitor { + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { + if let hir::TyKind::OpaqueDef(opaq) = ty.kind + && self.rpits.insert(opaq.def_id) + { + for bound in opaq.bounds { + intravisit::walk_param_bound(self, bound); + } + } + intravisit::walk_ty(self, ty) + } +} /// Given an `fn_def_id` of a trait or a trait implementation: /// @@ -177,23 +194,6 @@ fn associated_types_for_impl_traits_in_associated_fn( match tcx.def_kind(parent_def_id) { DefKind::Trait => { - struct RPITVisitor { - rpits: FxIndexSet, - } - - impl<'tcx> Visitor<'tcx> for RPITVisitor { - fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { - if let hir::TyKind::OpaqueDef(opaq) = ty.kind - && self.rpits.insert(opaq.def_id) - { - for bound in opaq.bounds { - intravisit::walk_param_bound(self, bound); - } - } - intravisit::walk_ty(self, ty) - } - } - let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; if let Some(output) = tcx.hir_get_fn_output(fn_def_id) { @@ -246,9 +246,23 @@ fn associated_type_for_impl_trait_in_trait( let trait_def_id = tcx.local_parent(fn_def_id); assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); + // Collect all opaque types in return position for the method and use + // the index as the disambiguator to make an unique def path. + let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; + visitor.visit_fn_ret_ty(tcx.hir_get_fn_output(fn_def_id).unwrap()); + let disambiguator = visitor.rpits.get_index_of(&opaque_ty_def_id).unwrap().try_into().unwrap(); + let span = tcx.def_span(opaque_ty_def_id); - // No name because this is an anonymous associated type. - let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, None, DefKind::AssocTy); + // Also use the method name to create an unique def path. + let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id())); + let trait_assoc_ty = tcx.at(span).create_def( + trait_def_id, + // No name because this is an anonymous associated type. + None, + DefKind::AssocTy, + Some(data), + &mut DisambiguatorState::with(trait_def_id, data, disambiguator), + ); let local_def_id = trait_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); @@ -299,8 +313,22 @@ fn associated_type_for_impl_trait_in_impl( hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id), hir::FnRetTy::Return(ty) => ty.span, }; - // No name because this is an anonymous associated type. - let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, None, DefKind::AssocTy); + + // Use the same disambiguator and method name as the anon associated type in the trait. + let disambiguated_data = tcx.def_key(trait_assoc_def_id).disambiguated_data; + let DefPathData::AnonAssocTy(name) = disambiguated_data.data else { + bug!("expected anon associated type") + }; + let data = DefPathData::AnonAssocTy(name); + + let impl_assoc_ty = tcx.at(span).create_def( + impl_local_def_id, + // No name because this is an anonymous associated type. + None, + DefKind::AssocTy, + Some(data), + &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator), + ); let local_def_id = impl_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr index cb14d9f459a2..53d05c3db8c4 100644 --- a/tests/ui/delegation/unsupported.stderr +++ b/tests/ui/delegation/unsupported.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when computing type of `opaque::::{anon_assoc#0}` +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` --> $DIR/unsupported.rs:22:25 | LL | reuse to_reuse::opaque_ret; @@ -9,7 +9,7 @@ note: ...which requires comparing an impl and trait method signature, inferring | LL | reuse to_reuse::opaque_ret; | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::{anon_assoc#0}`, completing the cycle + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle note: cycle used when checking that `opaque::` is well-formed --> $DIR/unsupported.rs:21:5 | @@ -17,7 +17,7 @@ LL | impl ToReuse for u8 { | ^^^^^^^^^^^^^^^^^^^ = 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[E0391]: cycle detected when computing type of `opaque::::{anon_assoc#0}` +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` --> $DIR/unsupported.rs:25:24 | LL | reuse ToReuse::opaque_ret; @@ -28,7 +28,7 @@ note: ...which requires comparing an impl and trait method signature, inferring | LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::{anon_assoc#0}`, completing the cycle + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle note: cycle used when checking that `opaque::` is well-formed --> $DIR/unsupported.rs:24:5 | diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr index a9dfac274d55..119195f17ffc 100644 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr +++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr @@ -6,11 +6,11 @@ LL | fn bar() -> () {} | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `Foo::{anon_assoc#0}` +note: required by a bound in `Foo::bar::{anon_assoc#0}` --> $DIR/doesnt-satisfy.rs:2:22 | LL | fn bar() -> impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{anon_assoc#0}` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{anon_assoc#0}` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/dump.rs b/tests/ui/impl-trait/in-trait/dump.rs index da3cfd099b56..0a951b4fd99a 100644 --- a/tests/ui/impl-trait/in-trait/dump.rs +++ b/tests/ui/impl-trait/in-trait/dump.rs @@ -8,7 +8,7 @@ trait Foo { } fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> { -//~^ ERROR ::{anon_assoc#0}<'s/#1> + //~^ ERROR ::hello::{anon_assoc#0}<'s/#1> x.hello() } diff --git a/tests/ui/impl-trait/in-trait/dump.stderr b/tests/ui/impl-trait/in-trait/dump.stderr index 15b6f186ced5..35ed21bde113 100644 --- a/tests/ui/impl-trait/in-trait/dump.stderr +++ b/tests/ui/impl-trait/in-trait/dump.stderr @@ -1,4 +1,4 @@ -error: ::{anon_assoc#0}<'s/#1> +error: ::hello::{anon_assoc#0}<'s/#1> --> $DIR/dump.rs:10:35 | LL | fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> { diff --git a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr index bf598d627094..5d6512457467 100644 --- a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr +++ b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when computing type of `::{anon_assoc#0}` +error[E0391]: cycle detected when computing type of `::foo::{anon_assoc#0}` --> $DIR/method-compatability-via-leakage-cycle.rs:21:24 | LL | fn foo(b: bool) -> impl Sized { @@ -45,7 +45,7 @@ note: ...which requires type-checking ` impl Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `::{anon_assoc#0}`, completing the cycle + = note: ...which again requires computing type of `::foo::{anon_assoc#0}`, completing the cycle note: cycle used when checking that `` is well-formed --> $DIR/method-compatability-via-leakage-cycle.rs:17:1 | diff --git a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr index 6bec5bbc0632..4bbba62bd710 100644 --- a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr +++ b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when computing type of `::{anon_assoc#0}` +error[E0391]: cycle detected when computing type of `::foo::{anon_assoc#0}` --> $DIR/method-compatability-via-leakage-cycle.rs:21:24 | LL | fn foo(b: bool) -> impl Sized { @@ -49,7 +49,7 @@ note: ...which requires type-checking ` impl Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `::{anon_assoc#0}`, completing the cycle + = note: ...which again requires computing type of `::foo::{anon_assoc#0}`, completing the cycle note: cycle used when checking that `` is well-formed --> $DIR/method-compatability-via-leakage-cycle.rs:17:1 | @@ -57,7 +57,7 @@ LL | impl Trait for u32 { | ^^^^^^^^^^^^^^^^^^ = 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[E0391]: cycle detected when computing type of `::{anon_assoc#0}` +error[E0391]: cycle detected when computing type of `::foo::{anon_assoc#0}` --> $DIR/method-compatability-via-leakage-cycle.rs:21:24 | LL | fn foo(b: bool) -> impl Sized { @@ -108,7 +108,7 @@ note: ...which requires type-checking ` impl Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `::{anon_assoc#0}`, completing the cycle + = note: ...which again requires computing type of `::foo::{anon_assoc#0}`, completing the cycle note: cycle used when checking that `` is well-formed --> $DIR/method-compatability-via-leakage-cycle.rs:17:1 | diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index 6571ce2d5f05..a16e0160223b 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -14,11 +14,11 @@ LL | fn foo>(self) -> impl Foo { | ^^^^^^^^^^^^ the trait `Foo` is not implemented for `impl Foo` | = help: the trait `Foo` is implemented for `Bar` -note: required by a bound in `Foo::{anon_assoc#0}` +note: required by a bound in `Foo::foo::{anon_assoc#0}` --> $DIR/return-dont-satisfy-bounds.rs:2:30 | LL | fn foo(self) -> impl Foo; - | ^^^^^^ required by this bound in `Foo::{anon_assoc#0}` + | ^^^^^^ required by this bound in `Foo::foo::{anon_assoc#0}` error[E0277]: the trait bound `Bar: Foo` is not satisfied --> $DIR/return-dont-satisfy-bounds.rs:8:34 diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr index 400969c279e6..99fd83e7b6ff 100644 --- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr +++ b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr @@ -4,11 +4,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied LL | fn main() -> Something { | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` | -note: required by a bound in `Main::{anon_assoc#0}` +note: required by a bound in `Main::main::{anon_assoc#0}` --> $DIR/issue-103052-2.rs:3:27 | LL | fn main() -> impl std::process::Termination; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{anon_assoc#0}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{anon_assoc#0}` error: aborting due to 1 previous error From 21e7003a025419af87bb315dc394beee0ba391e5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 29 Apr 2025 13:09:19 +0200 Subject: [PATCH 038/262] refactor: Remove unnecessary extension trait --- .../rust-analyzer/crates/hir-expand/src/db.rs | 5 +- .../crates/hir-expand/src/hygiene.rs | 60 +------------------ .../crates/hir-expand/src/mod_path.rs | 4 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 1 - .../rust-analyzer/crates/hir/src/semantics.rs | 1 - .../rust-analyzer/crates/span/src/hygiene.rs | 56 ++++++++++++++++- 6 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 2219a55a84be..67391dbd955a 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -18,10 +18,7 @@ use crate::{ cfg_process, declarative::DeclarativeMacroExpander, fixup::{self, SyntaxFixupUndoInfo}, - hygiene::{ - SyntaxContextExt as _, span_with_call_site_ctxt, span_with_def_site_ctxt, - span_with_mixed_site_ctxt, - }, + hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt}, proc_macro::{CrateProcMacros, CustomProcMacroExpander, ProcMacros}, span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef}, tt, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index e7856920bc42..28800c6fabdb 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -22,7 +22,7 @@ // FIXME: Move this into the span crate? Not quite possible today as that depends on `MacroCallLoc` // which contains a bunch of unrelated things -use std::{convert::identity, iter}; +use std::convert::identity; use span::{Edition, MacroCallId, Span, SyntaxContext}; @@ -141,61 +141,3 @@ fn apply_mark_internal( |_| opaque_and_semitransparent, ) } - -pub trait SyntaxContextExt { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext; - fn remove_mark(&mut self, db: &dyn ExpandDatabase) - -> (Option, Transparency); - fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)>; - fn is_opaque(self, db: &dyn ExpandDatabase) -> bool; -} - -impl SyntaxContextExt for SyntaxContext { - fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { - self.opaque_and_semitransparent(db) - } - fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { - self.opaque(db) - } - fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext { - self.parent(db) - } - fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency) { - let data = self; - (data.outer_expn(db), data.outer_transparency(db)) - } - fn remove_mark( - &mut self, - db: &dyn ExpandDatabase, - ) -> (Option, Transparency) { - let data = *self; - *self = data.parent(db); - (data.outer_expn(db), data.outer_transparency(db)) - } - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)> { - let mut marks = marks_rev(self, db).collect::>(); - marks.reverse(); - marks - } - fn is_opaque(self, db: &dyn ExpandDatabase) -> bool { - !self.is_root() && self.outer_transparency(db).is_opaque() - } -} - -// FIXME: Make this a SyntaxContextExt method once we have RPIT -pub fn marks_rev( - ctxt: SyntaxContext, - db: &dyn ExpandDatabase, -) -> impl Iterator + '_ { - iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db))) - .take_while(|&it| !it.is_root()) - .map(|ctx| { - let mark = ctx.outer_mark(db); - // We stop before taking the root expansion, as such we cannot encounter a `None` outer - // expansion, as only the ROOT has it. - (mark.0.unwrap(), mark.1) - }) -} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 72a5627636bf..9f1e3879e1ee 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ db::ExpandDatabase, - hygiene::{SyntaxContextExt, Transparency, marks_rev}, + hygiene::Transparency, name::{AsName, Name}, tt, }; @@ -340,7 +340,7 @@ pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContext) -> O // definitions actually produced by `macro` and `macro` definitions produced by // `macro_rules!`, but at least such configurations are not stable yet. ctxt = ctxt.normalize_to_macro_rules(db); - let mut iter = marks_rev(ctxt, db).peekable(); + let mut iter = ctxt.marks_rev(db).peekable(); let mut result_mark = None; // Find the last opaque mark from the end if it exists. while let Some(&(mark, Transparency::Opaque)) = iter.peek() { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index c62e4cf4497d..d7754bf2e233 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -136,7 +136,6 @@ pub use { HirFileRange, InFile, InFileWrapper, InMacroFile, InRealFile, MacroFilePosition, MacroFileRange, }, - hygiene::{SyntaxContextExt, marks_rev}, inert_attr_macro::AttributeTemplate, mod_path::{ModPath, PathKind, tool_path}, name::Name, diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f708f2e16673..2e693559e292 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -25,7 +25,6 @@ use hir_expand::{ builtin::{BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, files::{FileRangeWrapper, InRealFile}, - hygiene::SyntaxContextExt as _, inert_attr_macro::find_builtin_attr_idx, mod_path::{ModPath, PathKind}, name::AsName, diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index b21102f2db71..d1e75d97d7a7 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -308,7 +308,7 @@ impl SyntaxContext { } #[cfg(feature = "salsa")] -impl SyntaxContext { +impl<'db> SyntaxContext { const MAX_ID: u32 = salsa::Id::MAX_U32 - 1; #[inline] @@ -340,6 +340,60 @@ impl SyntaxContext { // SAFETY: This comes from a Salsa ID. unsafe { Self::from_u32(id.as_u32()) } } + + #[inline] + pub fn outer_mark( + self, + db: &'db dyn salsa::Database, + ) -> (Option, Transparency) { + (self.outer_expn(db), self.outer_transparency(db)) + } + + #[inline] + pub fn normalize_to_macros_2_0(self, db: &'db dyn salsa::Database) -> SyntaxContext { + self.opaque(db) + } + + #[inline] + pub fn normalize_to_macro_rules(self, db: &'db dyn salsa::Database) -> SyntaxContext { + self.opaque_and_semitransparent(db) + } + + pub fn is_opaque(self, db: &'db dyn salsa::Database) -> bool { + !self.is_root() && self.outer_transparency(db).is_opaque() + } + + pub fn remove_mark( + &mut self, + db: &'db dyn salsa::Database, + ) -> (Option, Transparency) { + let data = *self; + *self = data.parent(db); + (data.outer_expn(db), data.outer_transparency(db)) + } + + pub fn marks( + self, + db: &'db dyn salsa::Database, + ) -> impl Iterator { + let mut marks = self.marks_rev(db).collect::>(); + marks.reverse(); + marks.into_iter() + } + + pub fn marks_rev( + self, + db: &'db dyn salsa::Database, + ) -> impl Iterator { + std::iter::successors(Some(self), move |&mark| Some(mark.parent(db))) + .take_while(|&it| !it.is_root()) + .map(|ctx| { + let mark = ctx.outer_mark(db); + // We stop before taking the root expansion, as such we cannot encounter a `None` outer + // expansion, as only the ROOT has it. + (mark.0.unwrap(), mark.1) + }) + } } #[cfg(not(feature = "salsa"))] #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] From df1f8d140e637d927caa0610f47e320d75b76a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 29 Apr 2025 14:49:00 +0200 Subject: [PATCH 039/262] Update stable-mir test --- .../stable-mir/check_assoc_items.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/ui-fulldeps/stable-mir/check_assoc_items.rs b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs index 755bec8747bc..bb95bedf9733 100644 --- a/tests/ui-fulldeps/stable-mir/check_assoc_items.rs +++ b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs @@ -17,13 +17,13 @@ extern crate rustc_driver; extern crate rustc_interface; extern crate stable_mir; -use std::io::Write; use std::collections::HashSet; -use stable_mir::CrateDef; -use stable_mir::*; -use stable_mir::ty::*; +use std::io::Write; use std::ops::ControlFlow; +use stable_mir::ty::*; +use stable_mir::{CrateDef, *}; + const CRATE_NAME: &str = "crate_assoc_items"; /// This function uses the Stable MIR APIs to get information about the test crate. @@ -45,30 +45,30 @@ fn test_assoc_items() -> ControlFlow<()> { let local_impls = local_crate.trait_impls(); let local_traits = local_crate.trait_decls(); - let trait_assoc_item_defs: Vec = local_traits[0].associated_items() - .iter().map(|assoc_item| assoc_item.def_id).collect(); + let trait_assoc_item_defs: Vec = + local_traits[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect(); check_items( &trait_assoc_item_defs, &[ - "ATrait::{anon_assoc#0}", + "ATrait::rpitit::{anon_assoc#0}", "ATrait::rpitit", "ATrait::Assoc", "ATrait::assoc_fn_no_self", "ATrait::assoc_fn_has_self", - ] + ], ); - let impl_assoc_item_defs: Vec = local_impls[0].associated_items() - .iter().map(|assoc_item| assoc_item.def_id).collect(); + let impl_assoc_item_defs: Vec = + local_impls[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect(); check_items( &impl_assoc_item_defs, &[ - "::{anon_assoc#0}", + "::rpitit::{anon_assoc#0}", "::rpitit", "::Assoc", "::assoc_fn_no_self", "::assoc_fn_has_self", - ] + ], ); ControlFlow::Continue(()) From 820fce61e72a1bc9c8eb132afec9ab71c67f4923 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 29 Apr 2025 13:55:28 +0000 Subject: [PATCH 040/262] Some style nits --- compiler/rustc_mir_transform/src/shim.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 0d9a04b760a2..9688ac8ed2e2 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -298,10 +298,9 @@ fn local_decls_for_sig<'tcx>( fn dropee_emit_retag<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, - dropee_ptr: Place<'tcx>, + mut dropee_ptr: Place<'tcx>, span: Span, ) -> Place<'tcx> { - let mut dropee_ptr = dropee_ptr; if tcx.sess.opts.unstable_opts.mir_emit_retag { let source_info = SourceInfo::outermost(span); // We want to treat the function argument as if it was passed by `&mut`. As such, we @@ -365,8 +364,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); // The first argument (index 0), but add 1 for the return value. - let mut dropee_ptr = Place::from(Local::new(1 + 0)); - dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span); + let dropee_ptr = Place::from(Local::new(1 + 0)); + let dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span); if ty.is_some() { let patch = { From 9193dfe435559ff69c5b63b610c4e5ebac2ef23b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 29 Apr 2025 14:23:23 +0000 Subject: [PATCH 041/262] Use a closure instead of three chained iterators --- compiler/rustc_middle/src/mir/terminator.rs | 103 ++++++++---------- compiler/rustc_mir_transform/src/coroutine.rs | 6 +- .../rustc_mir_transform/src/jump_threading.rs | 4 +- compiler/rustc_mir_transform/src/prettify.rs | 4 +- .../src/remove_noop_landing_pads.rs | 4 +- compiler/rustc_mir_transform/src/simplify.rs | 9 +- 6 files changed, 58 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 8a1ead7d19d0..0834fa8844c0 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -437,8 +437,8 @@ impl<'tcx> Terminator<'tcx> { } #[inline] - pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { - self.kind.successors_mut() + pub fn successors_mut<'a>(&'a mut self, f: impl FnMut(&'a mut BasicBlock)) { + self.kind.successors_mut(f) } #[inline] @@ -486,7 +486,6 @@ pub use helper::*; mod helper { use super::*; pub type Successors<'a> = impl DoubleEndedIterator + 'a; - pub type SuccessorsMut<'a> = impl DoubleEndedIterator + 'a; impl SwitchTargets { /// Like [`SwitchTargets::target_for_value`], but returning the same type as @@ -560,69 +559,63 @@ mod helper { } #[inline] - #[define_opaque(SuccessorsMut)] - pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { + pub fn successors_mut<'a>(&'a mut self, mut f: impl FnMut(&'a mut BasicBlock)) { use self::TerminatorKind::*; - match *self { - // 3-successors for async drop: target, unwind, dropline (parent coroutine drop) - Drop { - target: ref mut t, - unwind: UnwindAction::Cleanup(ref mut u), - drop: Some(ref mut d), - .. - } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(Some(d))), - // 2-successors - Call { - target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. + match self { + Drop { target, unwind, drop, .. } => { + f(target); + if let UnwindAction::Cleanup(u) = unwind { + f(u) + } + if let Some(d) = drop { + f(d) + } } - | Yield { resume: ref mut t, drop: Some(ref mut u), .. } - | Drop { - target: ref mut t, - unwind: UnwindAction::Cleanup(ref mut u), - drop: None, - .. + Call { target, unwind, .. } => { + if let Some(target) = target { + f(target); + } + if let UnwindAction::Cleanup(u) = unwind { + f(u) + } } - | Drop { target: ref mut t, unwind: _, drop: Some(ref mut u), .. } - | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } - | FalseUnwind { - real_target: ref mut t, - unwind: UnwindAction::Cleanup(ref mut u), - } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(None)), - // single successor - Goto { target: ref mut t } - | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. } - | Call { target: Some(ref mut t), unwind: _, .. } - | Yield { resume: ref mut t, drop: None, .. } - | Drop { target: ref mut t, unwind: _, .. } - | Assert { target: ref mut t, unwind: _, .. } - | FalseUnwind { real_target: ref mut t, unwind: _ } => { - slice::from_mut(t).into_iter().chain(None.into_iter().chain(None)) + Yield { resume, drop, .. } => { + f(resume); + if let Some(d) = drop { + f(d) + } + } + Assert { target, unwind, .. } | FalseUnwind { real_target: target, unwind } => { + f(target); + if let UnwindAction::Cleanup(u) = unwind { + f(u) + } + } + Goto { target } => { + f(target); } - // No successors UnwindResume | UnwindTerminate(_) | CoroutineDrop | Return | Unreachable - | TailCall { .. } - | Call { target: None, unwind: _, .. } => { - (&mut []).into_iter().chain(None.into_iter().chain(None)) + | TailCall { .. } => {} + InlineAsm { targets, unwind, .. } => { + for target in targets { + f(target); + } + if let UnwindAction::Cleanup(u) = unwind { + f(u) + } } - // Multiple successors - InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => { - targets.iter_mut().chain(Some(u).into_iter().chain(None)) + SwitchInt { targets, .. } => { + for target in &mut targets.targets { + f(target); + } } - InlineAsm { ref mut targets, unwind: _, .. } => { - targets.iter_mut().chain(None.into_iter().chain(None)) - } - SwitchInt { ref mut targets, .. } => { - targets.targets.iter_mut().chain(None.into_iter().chain(None)) - } - // FalseEdge - FalseEdge { ref mut real_target, ref mut imaginary_target } => { - slice::from_mut(real_target) - .into_iter() - .chain(Some(imaginary_target).into_iter().chain(None)) + FalseEdge { real_target, imaginary_target } => { + f(real_target); + f(imaginary_target); } } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 263f0c40f5a5..66f106bec6fc 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1064,10 +1064,8 @@ fn insert_switch<'tcx>( }, ); - let blocks = body.basic_blocks_mut().iter_mut(); - - for target in blocks.flat_map(|b| b.terminator_mut().successors_mut()) { - *target += 1; + for b in body.basic_blocks_mut().iter_mut() { + b.terminator_mut().successors_mut(|target| *target += 1); } } diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 9732225e48dd..f1f5bcaaab11 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -765,12 +765,12 @@ impl OpportunitySet { // Replace `succ` by `new_succ` where it appears. let mut num_edges = 0; - for s in basic_blocks[current].terminator_mut().successors_mut() { + basic_blocks[current].terminator_mut().successors_mut(|s| { if *s == succ { *s = new_succ; num_edges += 1; } - } + }); // Update predecessors with the new block. let _new_succ = self.predecessors.push(num_edges); diff --git a/compiler/rustc_mir_transform/src/prettify.rs b/compiler/rustc_mir_transform/src/prettify.rs index 8ccfbe2f194b..8217feff24ec 100644 --- a/compiler/rustc_mir_transform/src/prettify.rs +++ b/compiler/rustc_mir_transform/src/prettify.rs @@ -115,9 +115,7 @@ impl<'tcx> MutVisitor<'tcx> for BasicBlockUpdater<'tcx> { } fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, _location: Location) { - for succ in terminator.successors_mut() { - *succ = self.map[*succ]; - } + terminator.successors_mut(|succ| *succ = self.map[*succ]); } } diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 1dd34005d664..797056ad52d4 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -58,13 +58,13 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads { } } - for target in body[bb].terminator_mut().successors_mut() { + body[bb].terminator_mut().successors_mut(|target| { if *target != resume_block && nop_landing_pads.contains(*target) { debug!(" folding noop jump to {:?} to resume block", target); *target = resume_block; jumps_folded += 1; } - } + }); let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads); if is_nop_landing_pad { diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 4f2cce8ac104..8f88228d9bbd 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -147,9 +147,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { let mut terminator = self.basic_blocks[bb].terminator.take().expect("invalid terminator state"); - for successor in terminator.successors_mut() { - self.collapse_goto_chain(successor, &mut changed); - } + terminator + .successors_mut(|successor| self.collapse_goto_chain(successor, &mut changed)); let mut inner_changed = true; merged_blocks.clear(); @@ -375,9 +374,7 @@ pub(super) fn remove_dead_blocks(body: &mut Body<'_>) { } for block in basic_blocks { - for target in block.terminator_mut().successors_mut() { - *target = replacements[target.index()]; - } + block.terminator_mut().successors_mut(|target| *target = replacements[target.index()]); } } From 0e139b899500a98af440e40e5dd1bf2c967a52f7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 29 Apr 2025 19:25:11 +0200 Subject: [PATCH 042/262] Update salsa --- src/tools/rust-analyzer/Cargo.lock | 12 ++-- src/tools/rust-analyzer/Cargo.toml | 2 +- .../rust-analyzer/crates/base-db/src/lib.rs | 58 +++++++++++++++++-- .../rust-analyzer/src/cli/rustc_tests.rs | 3 +- .../crates/rust-analyzer/src/diagnostics.rs | 4 +- .../rust-analyzer/src/handlers/dispatch.rs | 18 +++--- .../rust-analyzer/crates/span/src/hygiene.rs | 9 +-- src/tools/rust-analyzer/xtask/src/util.rs | 2 +- 8 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 9f6b80c63790..1542084d726a 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2033,9 +2033,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be22155f8d9732518b2db2bf379fe6f0b2375e76b08b7c8fe6c1b887d548c24" +checksum = "4deeb38b4c80ac90a8d4796f83da941b0d76c23783550d15d37eb43ccddcb5bc" dependencies = [ "boxcar", "crossbeam-queue", @@ -2056,15 +2056,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55a7ef0a84e336f7c5f0332d81727f5629fe042d2aa556c75307afebc9f78a5" +checksum = "a4e6166fa2802d86a77dbcae1bfe75f0ac46fdf952660c233ed64855a53dd603" [[package]] name = "salsa-macros" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0e88a9c0c0d231a63f83dcd1a2c5e5d11044fac4b65bc9ad3b68ab48b0a0ab" +checksum = "bf358e645a835d9901ee4d812d9812266e046ee92a28d2e37a73b7169a6503b7" dependencies = [ "heck", "proc-macro2", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 6fa171702dd4..191820d4e3f5 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -131,7 +131,7 @@ process-wrap = { version = "8.2.0", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.6", default-features = false } rayon = "1.10.0" -salsa = "0.20.0" +salsa = "0.21.0" semver = "1.0.26" serde = { version = "1.0.219" } serde_derive = { version = "1.0.219" } diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 1d73ba804a68..9275a58687ff 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -3,7 +3,7 @@ mod change; mod input; -use std::hash::BuildHasherDefault; +use std::{cell::RefCell, hash::BuildHasherDefault, panic, sync::Once}; pub use crate::{ change::FileChange, @@ -60,7 +60,7 @@ impl Files { match self.files.get(&file_id) { Some(text) => *text, None => { - panic!("Unable to fetch file text for `vfs::FileId`: {:?}; this is a bug", file_id) + panic!("Unable to fetch file text for `vfs::FileId`: {file_id:?}; this is a bug") } } } @@ -101,8 +101,7 @@ impl Files { let source_root = match self.source_roots.get(&source_root_id) { Some(source_root) => source_root, None => panic!( - "Unable to fetch `SourceRootInput` with `SourceRootId` ({:?}); this is a bug", - source_root_id + "Unable to fetch `SourceRootInput` with `SourceRootId` ({source_root_id:?}); this is a bug" ), }; @@ -132,8 +131,7 @@ impl Files { let file_source_root = match self.file_source_roots.get(&id) { Some(file_source_root) => file_source_root, None => panic!( - "Unable to get `FileSourceRootInput` with `vfs::FileId` ({:?}); this is a bug", - id + "Unable to get `FileSourceRootInput` with `vfs::FileId` ({id:?}); this is a bug", ), }; *file_source_root @@ -384,3 +382,51 @@ fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> { let source_root = db.file_source_root(file_id); db.source_root_crates(source_root.source_root_id(db)) } + +#[must_use] +pub struct DbPanicContext { + // prevent arbitrary construction + _priv: (), +} + +impl Drop for DbPanicContext { + fn drop(&mut self) { + Self::with_ctx(|ctx| assert!(ctx.pop().is_some())); + } +} + +impl DbPanicContext { + pub fn enter(frame: String) -> DbPanicContext { + #[expect(clippy::print_stderr, reason = "already panicking anyway")] + fn set_hook() { + let default_hook = panic::take_hook(); + panic::set_hook(Box::new(move |panic_info| { + DbPanicContext::with_ctx(|ctx| { + if !ctx.is_empty() { + eprintln!("Panic context:"); + for frame in ctx.iter() { + eprintln!("> {frame}\n"); + } + } + }); + if let Some(backtrace) = salsa::Backtrace::capture() { + eprintln!("{backtrace}"); + } + default_hook(panic_info); + })); + } + + static SET_HOOK: Once = Once::new(); + SET_HOOK.call_once(set_hook); + + Self::with_ctx(|ctx| ctx.push(frame)); + DbPanicContext { _priv: () } + } + + fn with_ctx(f: impl FnOnce(&mut Vec)) { + thread_local! { + static CTX: RefCell> = const { RefCell::new(Vec::new()) }; + } + CTX.with(|ctx| f(&mut ctx.borrow_mut())); + } +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index c042c26bd188..e3b372c91494 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -7,6 +7,7 @@ use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::Path use hir::{ChangeWithProcMacros, Crate}; use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig}; +use ide_db::base_db; use itertools::Either; use paths::Utf8PathBuf; use profile::StopWatch; @@ -310,7 +311,7 @@ impl flags::RustcTests { let tester = AssertUnwindSafe(&mut tester); let p = p.clone(); move || { - let _guard = stdx::panic_context::enter(p.display().to_string()); + let _guard = base_db::DbPanicContext::enter(p.display().to_string()); { tester }.0.test(p); } }) { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs index 9b1463b1126b..438a2a0ba1ea 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs @@ -5,7 +5,7 @@ use std::mem; use cargo_metadata::PackageId; use ide::FileId; -use ide_db::FxHashMap; +use ide_db::{FxHashMap, base_db::DbPanicContext}; use itertools::Itertools; use rustc_hash::FxHashSet; use stdx::iter_eq_by; @@ -215,7 +215,7 @@ pub(crate) fn fetch_native_diagnostics( kind: NativeDiagnosticsFetchKind, ) -> Vec<(FileId, Vec)> { let _p = tracing::info_span!("fetch_native_diagnostics").entered(); - let _ctx = stdx::panic_context::enter("fetch_native_diagnostics".to_owned()); + let _ctx = DbPanicContext::enter("fetch_native_diagnostics".to_owned()); // the diagnostics produced may point to different files not requested by the concrete request, // put those into here and filter later diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index 3b76edf528b6..f04ada38893a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -4,7 +4,10 @@ use std::{ panic, thread, }; -use ide_db::base_db::salsa::{self, Cancelled}; +use ide_db::base_db::{ + DbPanicContext, + salsa::{self, Cancelled}, +}; use lsp_server::{ExtractError, Response, ResponseError}; use serde::{Serialize, de::DeserializeOwned}; use stdx::thread::ThreadIntent; @@ -56,7 +59,7 @@ impl RequestDispatcher<'_> { tracing::info_span!("request", method = ?req.method, "request_id" = ?req.id).entered(); tracing::debug!(?params); let result = { - let _pctx = stdx::panic_context::enter(panic_context); + let _pctx = DbPanicContext::enter(panic_context); f(self.global_state, params) }; if let Ok(response) = result_to_response::(req.id, result) { @@ -86,7 +89,7 @@ impl RequestDispatcher<'_> { let global_state_snapshot = self.global_state.snapshot(); let result = panic::catch_unwind(move || { - let _pctx = stdx::panic_context::enter(panic_context); + let _pctx = DbPanicContext::enter(panic_context); f(global_state_snapshot, params) }); @@ -257,7 +260,7 @@ impl RequestDispatcher<'_> { } .spawn(intent, move || { let result = panic::catch_unwind(move || { - let _pctx = stdx::panic_context::enter(panic_context); + let _pctx = DbPanicContext::enter(panic_context); f(world, params) }); match thread_result_to_response::(req.id.clone(), result) { @@ -421,11 +424,8 @@ impl NotificationDispatcher<'_> { tracing::debug!(?params); - let _pctx = stdx::panic_context::enter(format!( - "\nversion: {}\nnotification: {}", - version(), - N::METHOD - )); + let _pctx = + DbPanicContext::enter(format!("\nversion: {}\nnotification: {}", version(), N::METHOD)); if let Err(e) = f(self.global_state, params) { tracing::error!(handler = %N::METHOD, error = %e, "notification handler failed"); } diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index d1e75d97d7a7..7bb88ac3658c 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -94,16 +94,11 @@ const _: () = { } } impl zalsa_struct_::Configuration for SyntaxContext { + const LOCATION: salsa::plumbing::Location = + salsa::plumbing::Location { file: file!(), line: line!() }; const DEBUG_NAME: &'static str = "SyntaxContextData"; type Fields<'a> = SyntaxContextData; type Struct<'a> = SyntaxContext; - fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> { - SyntaxContext::from_salsa_id(id) - } - fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { - s.as_salsa_id() - .expect("`SyntaxContext::deref_structs()` called on a root `SyntaxContext`") - } } impl SyntaxContext { pub fn ingredient(db: &Db) -> &zalsa_struct_::IngredientImpl diff --git a/src/tools/rust-analyzer/xtask/src/util.rs b/src/tools/rust-analyzer/xtask/src/util.rs index a740ad6afdcb..e5404d571717 100644 --- a/src/tools/rust-analyzer/xtask/src/util.rs +++ b/src/tools/rust-analyzer/xtask/src/util.rs @@ -37,7 +37,7 @@ pub(crate) fn detect_target(sh: &Shell) -> String { Ok(target) => target, _ => match cmd!(sh, "rustc --print=host-tuple").read() { Ok(target) => target, - Err(e) => panic!("Failed to detect target: {}\nPlease set RA_TARGET explicitly", e), + Err(e) => panic!("Failed to detect target: {e}\nPlease set RA_TARGET explicitly"), }, } } From 3f92794939d6cdc4919aa44e25fc1dafa80ba8de Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 29 Apr 2025 19:43:36 +0200 Subject: [PATCH 043/262] Split out salsa_macros Does not do much yet due to tracing pulling syn but oh well --- src/tools/rust-analyzer/Cargo.lock | 6 ++++++ src/tools/rust-analyzer/Cargo.toml | 3 ++- .../rust-analyzer/crates/base-db/Cargo.toml | 1 + .../rust-analyzer/crates/base-db/src/input.rs | 2 +- .../rust-analyzer/crates/base-db/src/lib.rs | 19 +++++++++++-------- .../rust-analyzer/crates/hir-def/Cargo.toml | 1 + .../crates/hir-def/src/lang_item.rs | 4 ++-- .../rust-analyzer/crates/hir-def/src/lib.rs | 14 +++++++------- .../crates/hir-def/src/test_db.rs | 6 +++--- .../crates/hir-expand/Cargo.toml | 1 + .../crates/hir-expand/src/change.rs | 3 +-- .../rust-analyzer/crates/hir-expand/src/db.rs | 2 +- .../crates/hir-expand/src/lib.rs | 4 ++-- .../rust-analyzer/crates/hir-ty/Cargo.toml | 1 + .../rust-analyzer/crates/hir-ty/src/lower.rs | 4 ++-- .../crates/hir-ty/src/test_db.rs | 6 +++--- .../rust-analyzer/crates/ide-db/Cargo.toml | 1 + .../rust-analyzer/crates/ide-db/src/lib.rs | 6 +++--- .../crates/query-group-macro/Cargo.toml | 1 + .../crates/query-group-macro/src/lib.rs | 8 ++++---- .../crates/query-group-macro/src/queries.rs | 2 +- .../query-group-macro/tests/interned.rs | 2 +- .../query-group-macro/tests/logger_db.rs | 4 ++-- .../query-group-macro/tests/old_and_new.rs | 8 ++++---- .../query-group-macro/tests/supertrait.rs | 2 +- 25 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 1542084d726a..d257988a57a0 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -85,6 +85,7 @@ dependencies = [ "query-group-macro", "rustc-hash 2.1.1", "salsa", + "salsa-macros", "semver", "span", "syntax", @@ -630,6 +631,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustc_apfloat", "salsa", + "salsa-macros", "smallvec", "span", "stdx", @@ -660,6 +662,7 @@ dependencies = [ "query-group-macro", "rustc-hash 2.1.1", "salsa", + "salsa-macros", "smallvec", "span", "stdx", @@ -700,6 +703,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustc_apfloat", "salsa", + "salsa-macros", "scoped-tls", "smallvec", "span", @@ -936,6 +940,7 @@ dependencies = [ "rayon", "rustc-hash 2.1.1", "salsa", + "salsa-macros", "span", "stdx", "syntax", @@ -1729,6 +1734,7 @@ dependencies = [ "proc-macro2", "quote", "salsa", + "salsa-macros", "syn", ] diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 191820d4e3f5..a29717d67abe 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -131,7 +131,8 @@ process-wrap = { version = "8.2.0", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.6", default-features = false } rayon = "1.10.0" -salsa = "0.21.0" +salsa = { version = "0.21.0", default-features = false, features = ["rayon","salsa_unstable"] } +salsa-macros = "0.21.0" semver = "1.0.26" serde = { version = "1.0.219" } serde_derive = { version = "1.0.219" } diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 441434504c29..e2e3253773fe 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -15,6 +15,7 @@ rust-version.workspace = true la-arena.workspace = true dashmap.workspace = true salsa.workspace = true +salsa-macros.workspace = true query-group.workspace = true rustc-hash.workspace = true triomphe.workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 499c9b3716b2..9660e6e87cca 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -392,7 +392,7 @@ impl BuiltDependency { pub type CratesIdMap = FxHashMap; -#[salsa::input] +#[salsa_macros::input] #[derive(Debug)] pub struct Crate { #[return_ref] diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 9275a58687ff..f7f4e024ef23 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -1,4 +1,8 @@ //! base_db defines basic database traits. The concrete DB is defined by ide. + +pub use salsa; +pub use salsa_macros; + // FIXME: Rename this crate, base db is non descriptive mod change; mod input; @@ -17,7 +21,6 @@ pub use crate::{ use dashmap::{DashMap, mapref::entry::Entry}; pub use query_group::{self}; use rustc_hash::{FxHashSet, FxHasher}; -pub use salsa::{self}; use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; use span::Edition; @@ -28,7 +31,7 @@ pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet} #[macro_export] macro_rules! impl_intern_key { ($id:ident, $loc:ident) => { - #[salsa::interned(no_lifetime)] + #[salsa_macros::interned(no_lifetime)] pub struct $id { pub loc: $loc, } @@ -161,7 +164,7 @@ impl Files { } } -#[salsa::interned(no_lifetime, debug, constructor=from_span)] +#[salsa_macros::interned(no_lifetime, debug, constructor=from_span)] pub struct EditionedFileId { pub editioned_file_id: span::EditionedFileId, } @@ -196,18 +199,18 @@ impl EditionedFileId { } } -#[salsa::input(debug)] +#[salsa_macros::input(debug)] pub struct FileText { pub text: Arc, pub file_id: vfs::FileId, } -#[salsa::input(debug)] +#[salsa_macros::input(debug)] pub struct FileSourceRootInput { pub source_root_id: SourceRootId, } -#[salsa::input(debug)] +#[salsa_macros::input(debug)] pub struct SourceRootInput { pub source_root: Arc, } @@ -274,7 +277,7 @@ pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet FileText; @@ -353,7 +356,7 @@ fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse Option<&[SyntaxError]> { - #[salsa::tracked(return_ref)] + #[salsa_macros::tracked(return_ref)] fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option> { let errors = db.parse(file_id).errors(); match &*errors { diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index f97597ffe5a6..c1c89e8d1cc3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -28,6 +28,7 @@ triomphe.workspace = true rustc_apfloat = "0.2.2" text-size.workspace = true salsa.workspace = true +salsa-macros.workspace = true query-group.workspace = true ra-ap-rustc_parse_format.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 6a4ac199b340..51a833b5f150 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -84,7 +84,7 @@ impl LangItemTarget { } /// Salsa query. This will look for lang items in a specific crate. -#[salsa::tracked(return_ref)] +#[salsa_macros::tracked(return_ref)] pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option> { let _p = tracing::info_span!("crate_lang_items_query").entered(); @@ -153,7 +153,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option for GenericDefId { } } -#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum CallableDefId { FunctionId(FunctionId), StructId(StructId), @@ -906,7 +906,7 @@ impl From for AttrDefId { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum VariantId { EnumVariantId(EnumVariantId), StructId(StructId), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index 2f7675134ca7..470975482951 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -19,7 +19,7 @@ use crate::{ src::HasSource, }; -#[salsa::db] +#[salsa_macros::db] #[derive(Clone)] pub(crate) struct TestDB { storage: salsa::Storage, @@ -44,7 +44,7 @@ impl Default for TestDB { } } -#[salsa::db] +#[salsa_macros::db] impl salsa::Database for TestDB { fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); @@ -63,7 +63,7 @@ impl fmt::Debug for TestDB { impl panic::RefUnwindSafe for TestDB {} -#[salsa::db] +#[salsa_macros::db] impl SourceDatabase for TestDB { fn file_text(&self, file_id: base_db::FileId) -> FileText { self.files.file_text(file_id) diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml index b83efca25528..ed818c5be3f7 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml @@ -21,6 +21,7 @@ smallvec.workspace = true triomphe.workspace = true query-group.workspace = true salsa.workspace = true +salsa-macros.workspace = true # local deps stdx.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs index 6873cb7eaf9c..3959741e6f13 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs @@ -1,7 +1,6 @@ //! Defines a unit of change that can applied to the database to get the next //! state. Changes are transactional. -use base_db::{CrateGraphBuilder, FileChange, SourceRoot}; -use salsa::Durability; +use base_db::{CrateGraphBuilder, FileChange, SourceRoot, salsa::Durability}; use span::FileId; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 67391dbd955a..7cb1b6c02075 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -144,7 +144,7 @@ pub trait ExpandDatabase: RootQueryDb { fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext; } -#[salsa::interned(no_lifetime, id = span::SyntaxContext)] +#[salsa_macros::interned(no_lifetime, id = span::SyntaxContext)] pub struct SyntaxContextWrapper { pub data: SyntaxContext, } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index ad35f7000a14..d844d8f41eef 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -1050,7 +1050,7 @@ impl ExpandTo { intern::impl_internable!(ModPath, attrs::AttrInput); -#[salsa::interned(no_lifetime, debug)] +#[salsa_macros::interned(no_lifetime, debug)] #[doc(alias = "MacroFileId")] pub struct MacroCallId { pub loc: MacroCallLoc, @@ -1070,7 +1070,7 @@ impl From for span::MacroCallId { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum HirFileId { FileId(EditionedFileId), MacroFile(MacroCallId), diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index 69ad7703c2ca..efa544cf3965 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -34,6 +34,7 @@ indexmap.workspace = true rustc_apfloat = "0.2.2" query-group.workspace = true salsa.workspace = true +salsa-macros.workspace = true ra-ap-rustc_abi.workspace = true ra-ap-rustc_index.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 6d7e58bea6a2..9def39d5f979 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1468,7 +1468,7 @@ fn type_for_enum_variant_constructor( } } -#[salsa::tracked(cycle_result = type_for_adt_cycle_result)] +#[salsa_macros::tracked(cycle_result = type_for_adt_cycle_result)] fn type_for_adt_tracked(db: &dyn HirDatabase, adt: AdtId) -> Binders { type_for_adt(db, adt) } @@ -1533,7 +1533,7 @@ pub enum TyDefId { } impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum ValueTyDefId { FunctionId(FunctionId), StructId(StructId), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index d2bba120b68e..bcd8aa6c4e95 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -16,7 +16,7 @@ use syntax::TextRange; use test_utils::extract_annotations; use triomphe::Arc; -#[salsa::db] +#[salsa_macros::db] #[derive(Clone)] pub(crate) struct TestDB { storage: salsa::Storage, @@ -47,7 +47,7 @@ impl fmt::Debug for TestDB { } } -#[salsa::db] +#[salsa_macros::db] impl SourceDatabase for TestDB { fn file_text(&self, file_id: base_db::FileId) -> FileText { self.files.file_text(file_id) @@ -102,7 +102,7 @@ impl SourceDatabase for TestDB { } } -#[salsa::db] +#[salsa_macros::db] impl salsa::Database for TestDB { fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml index f1d6b605b002..583318de26df 100644 --- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml @@ -24,6 +24,7 @@ arrayvec.workspace = true indexmap.workspace = true memchr = "2.7.4" salsa.workspace = true +salsa-macros.workspace = true query-group.workspace = true triomphe.workspace = true nohash-hasher.workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index a433f184e765..63cc7cde2808 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -76,7 +76,7 @@ pub type FxIndexMap = pub type FilePosition = FilePositionWrapper; pub type FileRange = FileRangeWrapper; -#[salsa::db] +#[salsa_macros::db] pub struct RootDatabase { // FIXME: Revisit this commit now that we migrated to the new salsa, given we store arcs in this // db directly now @@ -91,7 +91,7 @@ pub struct RootDatabase { impl std::panic::RefUnwindSafe for RootDatabase {} -#[salsa::db] +#[salsa_macros::db] impl salsa::Database for RootDatabase { fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } @@ -118,7 +118,7 @@ impl fmt::Debug for RootDatabase { } } -#[salsa::db] +#[salsa_macros::db] impl SourceDatabase for RootDatabase { fn file_text(&self, file_id: vfs::FileId) -> FileText { self.files.file_text(file_id) diff --git a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml index 8aeb26294231..8b03d8f8cc7a 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml +++ b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml @@ -20,3 +20,4 @@ syn = { version = "2.0", features = ["full", "extra-traits", "visit-mut"] } [dev-dependencies] expect-test = "1.5.1" salsa.workspace = true +salsa-macros.workspace = true diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs index 3ade12733a75..6b81928c91e1 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs @@ -178,7 +178,7 @@ pub(crate) fn query_group_impl( let supertraits = &item_trait.supertraits; let db_attr: Attribute = parse_quote! { - #[salsa::db] + #[salsa_macros::db] }; item_trait.attrs.push(db_attr); @@ -407,7 +407,7 @@ pub(crate) fn query_group_impl( .collect::>(); let input_struct = quote! { - #[salsa::input] + #[salsa_macros::input] pub(crate) struct #input_struct_name { #(#fields),* } @@ -418,7 +418,7 @@ pub(crate) fn query_group_impl( let create_data_method = quote! { #[allow(non_snake_case)] - #[salsa::tracked] + #[salsa_macros::tracked] fn #create_data_ident(db: &dyn #trait_name_ident) -> #input_struct_name { #input_struct_name::new(db, #(#field_params),*) } @@ -443,7 +443,7 @@ pub(crate) fn query_group_impl( item_trait.items.append(&mut lookup_signatures); let trait_impl = quote! { - #[salsa::db] + #[salsa_macros::db] impl #trait_name_ident for DB where DB: #supertraits, diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs index d4d40588bfc7..baac3e8bbfe7 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -49,7 +49,7 @@ impl ToTokens for TrackedQuery { }) .into_iter() .chain(self.lru.map(|lru| quote!(lru = #lru))); - let annotation = quote!(#[salsa::tracked( #(#options),* )]); + let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]); let pat_and_tys = &self.pat_and_tys; let params = self diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs index 26ed316122a5..f738185b1fe7 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs @@ -6,7 +6,7 @@ use salsa::plumbing::AsId; mod logger_db; use logger_db::LoggerDb; -#[salsa::interned(no_lifetime)] +#[salsa_macros::interned(no_lifetime)] pub struct InternedString { data: String, } diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs index 0bb86467c78b..bade0c2cd6fa 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs @@ -1,6 +1,6 @@ use std::sync::{Arc, Mutex}; -#[salsa::db] +#[salsa_macros::db] #[derive(Default, Clone)] pub(crate) struct LoggerDb { storage: salsa::Storage, @@ -12,7 +12,7 @@ struct Logger { logs: Arc>>, } -#[salsa::db] +#[salsa_macros::db] impl salsa::Database for LoggerDb { fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { let event = event(); diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs index a18b23a7d8a9..cc57ba78455f 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs @@ -4,7 +4,7 @@ mod logger_db; use logger_db::LoggerDb; use query_group_macro::query_group; -#[salsa::input] +#[salsa_macros::input] struct Input { str: String, } @@ -30,7 +30,7 @@ fn invoke_length_query_actual(db: &dyn PartialMigrationDatabase, input: Input) - input.str(db).len() } -#[salsa::tracked] +#[salsa_macros::tracked] fn invoke_length_tracked_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize { input.str(db).len() } @@ -87,12 +87,12 @@ fn invoke_tracked_query() { fn new_salsa_baseline() { let db = LoggerDb::default(); - #[salsa::input] + #[salsa_macros::input] struct Input { str: String, } - #[salsa::tracked] + #[salsa_macros::tracked] fn new_salsa_length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize { input.str(db).len() } diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs index 70073ac1de32..ad8ada3ef153 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs @@ -1,6 +1,6 @@ use query_group_macro::query_group; -#[salsa::db] +#[salsa_macros::db] pub trait SourceDb: salsa::Database { /// Text of the file. fn file_text(&self, id: usize) -> String; From dd20225681cf581066afab23db0c0d854806370d Mon Sep 17 00:00:00 2001 From: Jon Bauman Date: Tue, 29 Apr 2025 11:24:31 -0700 Subject: [PATCH 044/262] Update rc.rs docs `wrapped_add` is used, not `checked_add` --- library/alloc/src/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 619d9f258e34..247afc628326 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -3536,7 +3536,7 @@ impl Default for Weak { } } -// NOTE: We checked_add here to deal with mem::forget safely. In particular +// NOTE: We wrapping_add here to deal with mem::forget safely. In particular // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then // you can free the allocation while outstanding Rcs (or Weaks) exist. // We abort because this is such a degenerate scenario that we don't care about From 1b677ce14ff759dacadd5d4b05dd27a00bfd68c2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 30 Apr 2025 07:34:00 +0200 Subject: [PATCH 045/262] chore: Adjust panic context printing --- .../rust-analyzer/crates/base-db/src/lib.rs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index f7f4e024ef23..a67fbf75c02f 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -387,10 +387,8 @@ fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> { } #[must_use] -pub struct DbPanicContext { - // prevent arbitrary construction - _priv: (), -} +#[non_exhaustive] +pub struct DbPanicContext; impl Drop for DbPanicContext { fn drop(&mut self) { @@ -404,18 +402,18 @@ impl DbPanicContext { fn set_hook() { let default_hook = panic::take_hook(); panic::set_hook(Box::new(move |panic_info| { + default_hook(panic_info); + if let Some(backtrace) = salsa::Backtrace::capture() { + eprintln!("{backtrace:#}"); + } DbPanicContext::with_ctx(|ctx| { if !ctx.is_empty() { - eprintln!("Panic context:"); - for frame in ctx.iter() { - eprintln!("> {frame}\n"); + eprintln!("additional context:"); + for (idx, frame) in ctx.iter().enumerate() { + eprintln!("{idx:>4}: {frame}\n"); } } }); - if let Some(backtrace) = salsa::Backtrace::capture() { - eprintln!("{backtrace}"); - } - default_hook(panic_info); })); } @@ -423,7 +421,7 @@ impl DbPanicContext { SET_HOOK.call_once(set_hook); Self::with_ctx(|ctx| ctx.push(frame)); - DbPanicContext { _priv: () } + DbPanicContext } fn with_ctx(f: impl FnOnce(&mut Vec)) { From 146d8b95c88a9705449a2e3c65867efeed09602b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 30 Apr 2025 09:14:12 +0200 Subject: [PATCH 046/262] Update to LLVM 20.1.4 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index a9865ceca081..8448283b4bd3 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit a9865ceca08101071e25f3bba97bba8bf0ea9719 +Subproject commit 8448283b4bd34ea00d76fd4f18ec730b549d6e1d From d6ae459af8da8f5c751ad5cd8765a48778e419bb Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Apr 2025 15:09:34 +0200 Subject: [PATCH 047/262] Stabilize proc_macro::Span::{file, local_file}. --- library/proc_macro/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 36a1c57b0201..7dbb9dadd881 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -544,7 +544,7 @@ impl Span { /// /// This might not correspond to a valid file system path. /// It might be remapped, or might be an artificial path such as `""`. - #[unstable(feature = "proc_macro_span", issue = "54725")] + #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")] pub fn file(&self) -> String { self.0.file() } @@ -554,7 +554,7 @@ impl Span { /// This is the actual path on disk. It is unaffected by path remapping. /// /// This path should not be embedded in the output of the macro; prefer `file()` instead. - #[unstable(feature = "proc_macro_span", issue = "54725")] + #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")] pub fn local_file(&self) -> Option { self.0.local_file().map(|s| PathBuf::from(s)) } From 2a053c7a1532da2d8f60ac5a8f92b3e4e80d82d5 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Apr 2025 15:14:20 +0200 Subject: [PATCH 048/262] Update doc comments. --- library/proc_macro/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 7dbb9dadd881..79e9b8430b8d 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -543,13 +543,13 @@ impl Span { /// The path to the source file in which this span occurs, for display purposes. /// /// This might not correspond to a valid file system path. - /// It might be remapped, or might be an artificial path such as `""`. + /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `""`). #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")] pub fn file(&self) -> String { self.0.file() } - /// The path to the source file in which this span occurs on disk. + /// The path to the source file in which this span occurs on the local file system. /// /// This is the actual path on disk. It is unaffected by path remapping. /// From 09188e63f2ccb82b268cec305777266818f29542 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 30 Apr 2025 15:51:58 +0200 Subject: [PATCH 049/262] fix: Improve parser recovery a bit --- .../macro_expansion_tests/builtin_fn_macro.rs | 2 -- .../ide-completion/src/context/analysis.rs | 6 ++-- .../crates/parser/src/grammar/expressions.rs | 2 +- .../parser/src/grammar/expressions/atom.rs | 4 +-- .../crates/parser/src/grammar/items.rs | 3 ++ .../crates/parser/src/grammar/paths.rs | 2 +- .../crates/parser/src/grammar/patterns.rs | 15 ++++++++-- .../crates/parser/src/grammar/types.rs | 5 ++++ .../parser/test_data/generated/runner.rs | 4 +++ .../test_data/parser/err/0022_bad_exprs.rast | 7 +++-- .../comma_after_default_values_syntax.rast | 9 +++--- .../inline/err/struct_field_recover.rast | 30 +++++++++++++++++++ .../parser/inline/err/struct_field_recover.rs | 1 + .../inline/err/type_in_array_recover.rast | 15 ++++++++++ .../inline/err/type_in_array_recover.rs | 1 + 15 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs index a3b48831a0b0..e21d1415aa29 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -285,8 +285,6 @@ fn main() { /* parse error: expected expression */ builtin #format_args (x = ); /* parse error: expected expression */ -/* parse error: expected R_PAREN */ -/* parse error: expected expression, item or let statement */ builtin #format_args (x = , x = 2); /* parse error: expected expression */ builtin #format_args ("{}", x = ); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 595997358966..822dae2578e7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -661,9 +661,8 @@ fn expected_type_and_name( )) } else { cov_mark::hit!(expected_type_struct_field_without_leading_char); - let expr_field = token.prev_sibling_or_token()? - .into_node() - .and_then(ast::RecordExprField::cast)?; + cov_mark::hit!(expected_type_struct_field_followed_by_comma); + let expr_field = previous_non_trivia_token(token.clone())?.parent().and_then(ast::RecordExprField::cast)?; let (_, _, ty) = sema.resolve_record_field(&expr_field)?; Some(( Some(ty), @@ -681,7 +680,6 @@ fn expected_type_and_name( .or_else(|| sema.type_of_expr(&expr).map(TypeInfo::original)); (ty, field_name) } else { - cov_mark::hit!(expected_type_struct_field_followed_by_comma); (field_ty, field_name) } }, diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs index 34dcf2a18229..0ac25da32941 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs @@ -4,7 +4,7 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST; use super::*; -pub(super) use atom::{LITERAL_FIRST, literal}; +pub(super) use atom::{EXPR_RECOVERY_SET, LITERAL_FIRST, literal}; pub(crate) use atom::{block_expr, match_arm_list}; #[derive(PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index c66afed91c51..5faf6fc2759e 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -46,7 +46,6 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = T!['['], T![|], T![async], - T![box], T![break], T![const], T![continue], @@ -68,7 +67,8 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = LIFETIME_IDENT, ])); -pub(super) const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[T![')'], T![']']]); +pub(in crate::grammar) const EXPR_RECOVERY_SET: TokenSet = + TokenSet::new(&[T!['}'], T![')'], T![']'], T![,]]); pub(super) fn atom_expr( p: &mut Parser<'_>, diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs index f5f003be4891..b9f4866574a6 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs @@ -32,6 +32,9 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[ T![impl], T![trait], T![const], + T![async], + T![unsafe], + T![extern], T![static], T![let], T![mod], diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs index 3410505cd46d..770827c6b0d4 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs @@ -81,7 +81,7 @@ fn path_for_qualifier( } const EXPR_PATH_SEGMENT_RECOVERY_SET: TokenSet = - items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![')'], T![,], T![let]])); + expressions::EXPR_RECOVERY_SET.union(items::ITEM_RECOVERY_SET); const TYPE_PATH_SEGMENT_RECOVERY_SET: TokenSet = types::TYPE_RECOVERY_SET; fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option { diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs index 460051a0f4a5..4dd44c030f30 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs @@ -199,8 +199,19 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) { } } -const PAT_RECOVERY_SET: TokenSet = - TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,], T![=]]); +const PAT_RECOVERY_SET: TokenSet = TokenSet::new(&[ + T![let], + T![if], + T![while], + T![loop], + T![match], + T![')'], + T![']'], + T!['}'], + T![,], + T![=], + T![&], +]); fn atom_pat(p: &mut Parser<'_>, recovery_set: TokenSet) -> Option { let m = match p.current() { diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs index 0133b7d5d820..9d31e435cf98 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs @@ -20,10 +20,15 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[ pub(super) const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[ T![')'], + // test_err type_in_array_recover + // const _: [&]; + T![']'], + T!['}'], T![>], T![,], // test_err struct_field_recover // struct S { f pub g: () } + // struct S { f: pub g: () } T![pub], ]); diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 6c9d02aaa8f8..24db9478ee56 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -870,6 +870,10 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs"); } #[test] + fn type_in_array_recover() { + run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs"); + } + #[test] fn unsafe_block_in_mod() { run_and_expect_errors("test_data/parser/inline/err/unsafe_block_in_mod.rs"); } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast index d97fc6c72091..1a8e881dd9e0 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast @@ -35,8 +35,8 @@ SOURCE_FILE WHITESPACE " " LET_STMT LET_KW "let" - ERROR - R_BRACK "]" + ERROR + R_BRACK "]" WHITESPACE " " R_CURLY "}" WHITESPACE "\n" @@ -149,7 +149,8 @@ error 17: expected expression, item or let statement error 25: expected a name error 26: expected `;`, `{`, or `(` error 30: expected pattern -error 31: expected SEMICOLON +error 30: expected SEMICOLON +error 30: expected expression, item or let statement error 53: expected expression error 54: expected R_PAREN error 54: expected SEMICOLON diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast index feb617e1aa2a..b57066f2fb38 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast @@ -23,8 +23,7 @@ SOURCE_FILE L_CURLY "{" WHITESPACE " " DOT2 ".." - ERROR - COMMA "," + COMMA "," WHITESPACE " " R_CURLY "}" SEMICOLON ";" @@ -39,8 +38,7 @@ SOURCE_FILE L_CURLY "{" WHITESPACE " " DOT2 ".." - ERROR - COMMA "," + COMMA "," WHITESPACE " " RECORD_EXPR_FIELD NAME_REF @@ -55,5 +53,6 @@ SOURCE_FILE R_CURLY "}" WHITESPACE "\n" error 21: expected expression +error 21: cannot use a comma after the base struct error 36: expected expression -error 37: expected COMMA +error 36: cannot use a comma after the base struct diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast index 458d7f4e2fa2..5a12c21b647d 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast @@ -26,6 +26,36 @@ SOURCE_FILE WHITESPACE " " R_CURLY "}" WHITESPACE "\n" + STRUCT + STRUCT_KW "struct" + WHITESPACE " " + NAME + IDENT "S" + WHITESPACE " " + RECORD_FIELD_LIST + L_CURLY "{" + WHITESPACE " " + RECORD_FIELD + NAME + IDENT "f" + COLON ":" + WHITESPACE " " + RECORD_FIELD + VISIBILITY + PUB_KW "pub" + WHITESPACE " " + NAME + IDENT "g" + COLON ":" + WHITESPACE " " + TUPLE_TYPE + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n" error 12: expected COLON error 12: expected type error 12: expected COMMA +error 38: expected type +error 38: expected COMMA diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs index da32227adcd7..5b1e5a5b8a21 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs @@ -1 +1,2 @@ struct S { f pub g: () } +struct S { f: pub g: () } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast new file mode 100644 index 000000000000..db76e8d7c88a --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast @@ -0,0 +1,15 @@ +SOURCE_FILE + CONST + CONST_KW "const" + WHITESPACE " " + UNDERSCORE "_" + COLON ":" + WHITESPACE " " + SLICE_TYPE + L_BRACK "[" + REF_TYPE + AMP "&" + R_BRACK "]" + SEMICOLON ";" + WHITESPACE "\n" +error 11: expected type diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs new file mode 100644 index 000000000000..039bf8299779 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs @@ -0,0 +1 @@ +const _: [&]; From 0f81fca8ec623e849225a254ef6f639963ff54c0 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Wed, 30 Apr 2025 15:39:52 -0700 Subject: [PATCH 050/262] Change rustc_driver dependency on stable_mir crate This fixes issues with RustAnalyzer not finding stable_mir crate. It is also part of the long term architecture plan for these crates, since we are moving towards having stable_mir depend on rustc_smir and not the other way around. I believe this is an utility function that will come handy eventually for stable_mir users, but I'm keeping it as part of rustc_internal since it initializes the StableMir context and requires `TyCtxt`. Finally, I added the rustc_internal crate under a feature since the APIs from this module shall not be stabilized. --- Cargo.lock | 2 +- compiler/rustc_driver_impl/Cargo.toml | 2 +- compiler/rustc_driver_impl/src/pretty.rs | 2 +- compiler/stable_mir/Cargo.toml | 6 ++++++ compiler/stable_mir/src/lib.rs | 4 ++++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60daa453c60d..821512a53c2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3583,13 +3583,13 @@ dependencies = [ "rustc_query_system", "rustc_resolve", "rustc_session", - "rustc_smir", "rustc_span", "rustc_target", "rustc_trait_selection", "rustc_ty_utils", "serde_json", "shlex", + "stable_mir", "tracing", "windows 0.59.0", ] diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index c823d11126e2..9da4f2dbc273 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -44,13 +44,13 @@ rustc_privacy = { path = "../rustc_privacy" } rustc_query_system = { path = "../rustc_query_system" } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } -rustc_smir = { path = "../rustc_smir" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" +stable_mir = { path = "../stable_mir", features = ["rustc_internal"] } tracing = { version = "0.1.35" } # tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 16d70af7e05d..ec77043cd128 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -10,8 +10,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_build::thir::print::{thir_flat, thir_tree}; use rustc_session::Session; use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode}; -use rustc_smir::rustc_internal::pretty::write_smir_pretty; use rustc_span::{FileName, Ident}; +use stable_mir::rustc_internal::pretty::write_smir_pretty; use tracing::debug; use {rustc_ast as ast, rustc_hir_pretty as pprust_hir}; diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index 3a01ee5783ee..516c8e9c718b 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -5,3 +5,9 @@ edition = "2024" [dependencies] rustc_smir = { path = "../rustc_smir" } + +[features] +# Provides access to APIs that expose internals of the rust compiler. +# APIs enabled by this feature are unstable. They can be removed or modified +# at any point and they are not included in the crate's semantic versioning. +rustc_internal = [] diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index cc0fb52433d9..688f3936b26c 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -4,4 +4,8 @@ //! This is a transitional measure as described in [PR #139319](https://github.com/rust-lang/rust/pull/139319). //! Once the refactoring is complete, the `stable_mir` implementation will be moved back here. +/// Export the rustc_internal APIs. Note that this module has no stability +/// guarantees and it is not taken into account for semver. +#[cfg(feature = "rustc_internal")] +pub use rustc_smir::rustc_internal; pub use rustc_smir::stable_mir::*; From f27ba892bd9cd535aa3674496dfa217b875539a6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 30 Apr 2025 17:52:10 -0700 Subject: [PATCH 051/262] Update hashbrown dependency to unblock ExtractIf improvements --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 361d237b3af8..b45dec0d7cd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,9 +1502,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", From a6b8abf341013a9f13423a0012ab0fa096a825c7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 May 2025 07:27:32 +0200 Subject: [PATCH 052/262] Bump salsa --- src/tools/rust-analyzer/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index a29717d67abe..dd39cf59bb44 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -131,8 +131,8 @@ process-wrap = { version = "8.2.0", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.6", default-features = false } rayon = "1.10.0" -salsa = { version = "0.21.0", default-features = false, features = ["rayon","salsa_unstable"] } -salsa-macros = "0.21.0" +salsa = { version = "0.21.1", default-features = false, features = ["rayon","salsa_unstable"] } +salsa-macros = "0.21.1" semver = "1.0.26" serde = { version = "1.0.219" } serde_derive = { version = "1.0.219" } From 408232fb51b89cf543f1fe85c250b764656c8ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Thu, 1 May 2025 10:21:46 +0300 Subject: [PATCH 053/262] Update lockfile --- src/tools/rust-analyzer/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index d257988a57a0..8d6c8284e44e 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2039,9 +2039,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4deeb38b4c80ac90a8d4796f83da941b0d76c23783550d15d37eb43ccddcb5bc" +checksum = "6f80d5cf3c3fcab2cef898012f242a670477a1baa609267376af9cb4409026c5" dependencies = [ "boxcar", "crossbeam-queue", @@ -2062,15 +2062,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e6166fa2802d86a77dbcae1bfe75f0ac46fdf952660c233ed64855a53dd603" +checksum = "05303d72606fbf2b9c9523cda2039bb8ecb00304027a3cd7e52b02a65c7d9185" [[package]] name = "salsa-macros" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf358e645a835d9901ee4d812d9812266e046ee92a28d2e37a73b7169a6503b7" +checksum = "eb2f0e2a30c65cb3cd63440c491dde68d9af7e1be2b77832ac7057141107db50" dependencies = [ "heck", "proc-macro2", From b01b98f9f0b350badf8390e7950759d78484622d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Thu, 1 May 2025 10:21:52 +0300 Subject: [PATCH 054/262] Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 09c127f6bcd8..90e4d65bf961 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -21079f53a359d9fc82668d4175d49dafdb600563 +6e23095adf9209614a45f7f75fea36dad7b92afb From d3ec14bbec7d3647a3c1a3bfdf2cafb0f72bf937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 11 Apr 2025 21:27:53 +0200 Subject: [PATCH 055/262] Use thread local dep graph encoding --- compiler/rustc_data_structures/src/sync.rs | 2 +- .../src/sync/parallel.rs | 10 + .../rustc_incremental/src/persist/save.rs | 13 +- .../rustc_query_system/src/dep_graph/graph.rs | 76 ++-- .../rustc_query_system/src/dep_graph/mod.rs | 3 +- .../src/dep_graph/serialized.rs | 371 +++++++++++------- 6 files changed, 290 insertions(+), 185 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 80d49effbf8a..b28c333d860c 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -43,7 +43,7 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard}; pub use self::lock::{Lock, LockGuard, Mode}; pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; pub use self::parallel::{ - join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in, + broadcast, join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in, }; pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec}; pub use self::worker_local::{Registry, WorkerLocal}; diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 64db39cc4c6e..ab65c7f3a6b5 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -237,3 +237,13 @@ pub fn par_map, R: DynSend, C: FromIterato } }) } + +pub fn broadcast(op: impl Fn(usize) -> R + DynSync) -> Vec { + if mode::is_dyn_thread_safe() { + let op = FromDyn::from(op); + let results = rayon_core::broadcast(|context| op.derive(op(context.index()))); + results.into_iter().map(|r| r.into_inner()).collect() + } else { + vec![op(0)] + } +} diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 94ce6d9fa81f..58fea3278a83 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -44,10 +44,6 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { sess.time("assert_dep_graph", || assert_dep_graph(tcx)); sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx)); - if sess.opts.unstable_opts.incremental_info { - tcx.dep_graph.print_incremental_info() - } - join( move || { sess.time("incr_comp_persist_dep_graph", || { @@ -172,12 +168,5 @@ pub(crate) fn build_dep_graph( // First encode the commandline arguments hash sess.opts.dep_tracking_hash(false).encode(&mut encoder); - Some(DepGraph::new( - sess, - prev_graph, - prev_work_products, - encoder, - sess.opts.unstable_opts.query_dep_graph, - sess.opts.unstable_opts.incremental_info, - )) + Some(DepGraph::new(sess, prev_graph, prev_work_products, encoder)) } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 0d56db160996..180a2c9edf67 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -11,7 +11,7 @@ use rustc_data_structures::outline; use rustc_data_structures::profiling::QueryInvocationId; use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{AtomicU64, Lock}; +use rustc_data_structures::sync::{AtomicU64, Lock, is_dyn_thread_safe}; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; use rustc_index::IndexVec; @@ -124,19 +124,11 @@ impl DepGraph { prev_graph: Arc, prev_work_products: WorkProductMap, encoder: FileEncoder, - record_graph: bool, - record_stats: bool, ) -> DepGraph { let prev_graph_node_count = prev_graph.node_count(); - let current = CurrentDepGraph::new( - session, - prev_graph_node_count, - encoder, - record_graph, - record_stats, - Arc::clone(&prev_graph), - ); + let current = + CurrentDepGraph::new(session, prev_graph_node_count, encoder, Arc::clone(&prev_graph)); let colors = DepNodeColorMap::new(prev_graph_node_count); @@ -1052,17 +1044,8 @@ impl DepGraph { } } - pub fn print_incremental_info(&self) { - if let Some(data) = &self.data { - data.current.encoder.print_incremental_info( - data.current.total_read_count.load(Ordering::Relaxed), - data.current.total_duplicate_read_count.load(Ordering::Relaxed), - ) - } - } - pub fn finish_encoding(&self) -> FileEncodeResult { - if let Some(data) = &self.data { data.current.encoder.finish() } else { Ok(0) } + if let Some(data) = &self.data { data.current.encoder.finish(&data.current) } else { Ok(0) } } pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex { @@ -1179,8 +1162,8 @@ pub(super) struct CurrentDepGraph { /// These are simple counters that are for profiling and /// debugging and only active with `debug_assertions`. - total_read_count: AtomicU64, - total_duplicate_read_count: AtomicU64, + pub(super) total_read_count: AtomicU64, + pub(super) total_duplicate_read_count: AtomicU64, } impl CurrentDepGraph { @@ -1188,8 +1171,6 @@ impl CurrentDepGraph { session: &Session, prev_graph_node_count: usize, encoder: FileEncoder, - record_graph: bool, - record_stats: bool, previous: Arc, ) -> Self { let mut stable_hasher = StableHasher::new(); @@ -1211,14 +1192,7 @@ impl CurrentDepGraph { session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions); CurrentDepGraph { - encoder: GraphEncoder::new( - encoder, - prev_graph_node_count, - record_graph, - record_stats, - &session.prof, - previous, - ), + encoder: GraphEncoder::new(session, encoder, prev_graph_node_count, previous), anon_node_to_index: ShardedHashMap::with_capacity( // FIXME: The count estimate is off as anon nodes are only a portion of the nodes. new_node_count_estimate / sharded::shards(), @@ -1345,6 +1319,7 @@ impl Default for TaskDeps { // array, using one u32 per entry. pub(super) struct DepNodeColorMap { values: IndexVec, + sync: bool, } const COMPRESSED_NONE: u32 = u32::MAX; @@ -1353,7 +1328,10 @@ const COMPRESSED_RED: u32 = u32::MAX - 1; impl DepNodeColorMap { fn new(size: usize) -> DepNodeColorMap { debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32); - DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() } + DepNodeColorMap { + values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(), + sync: is_dyn_thread_safe(), + } } #[inline] @@ -1362,6 +1340,36 @@ impl DepNodeColorMap { if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None } } + /// This tries to atomically mark a node green and assign `index` as the new + /// index. + #[inline] + pub(super) fn try_mark_green( + &self, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, + ) -> Result<(), DepNodeIndex> { + let value = &self.values[prev_index]; + if self.sync { + match value.compare_exchange( + COMPRESSED_NONE, + index.as_u32(), + Ordering::Relaxed, + Ordering::Relaxed, + ) { + Ok(_) => Ok(()), + Err(v) => Err(DepNodeIndex::from_u32(v)), + } + } else { + let v = value.load(Ordering::Relaxed); + if v == COMPRESSED_NONE { + value.store(index.as_u32(), Ordering::Relaxed); + Ok(()) + } else { + Err(DepNodeIndex::from_u32(v)) + } + } + } + #[inline] pub(super) fn get(&self, index: SerializedDepNodeIndex) -> Option { match self.values[index].load(Ordering::Acquire) { diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 3a80835afad5..89d1db878095 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -12,6 +12,7 @@ pub(crate) use graph::DepGraphData; pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result}; pub use query::DepGraphQuery; use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_data_structures::sync::DynSync; use rustc_session::Session; pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; use tracing::instrument; @@ -89,7 +90,7 @@ pub trait DepContext: Copy { } } -pub trait Deps { +pub trait Deps: DynSync { /// Execute the operation with provided dependencies. fn with_deps(deps: TaskDepsRef<'_>, op: OP) -> R where diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index d2bcde143835..e88d95b6b074 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -35,23 +35,27 @@ //! If the number of edges in this node does not fit in the bits available in the header, we //! store it directly after the header with leb128. -use std::iter; +use std::cell::RefCell; +use std::cmp::max; use std::marker::PhantomData; use std::sync::Arc; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::{iter, mem, u64}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::outline; use rustc_data_structures::profiling::SelfProfilerRef; -use rustc_data_structures::sync::Lock; +use rustc_data_structures::sync::{Lock, WorkerLocal, broadcast}; use rustc_data_structures::unhash::UnhashMap; -use rustc_index::{Idx, IndexVec}; +use rustc_index::IndexVec; use rustc_serialize::opaque::mem_encoder::MemEncoder; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use rustc_session::Session; use tracing::{debug, instrument}; -use super::graph::{DepNodeColor, DepNodeColorMap}; +use super::graph::{CurrentDepGraph, DepNodeColor, DepNodeColorMap}; use super::query::DepGraphQuery; use super::{DepKind, DepNode, DepNodeIndex, Deps}; use crate::dep_graph::edges::EdgesVec; @@ -76,6 +80,9 @@ const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1; const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2; /// Data for use when recompiling the **current crate**. +/// +/// There may be unused indices with DEP_KIND_NULL in this graph due to batch allocation of +/// indices to threads. #[derive(Debug, Default)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph @@ -184,26 +191,30 @@ impl SerializedDepGraph { pub fn decode(d: &mut MemDecoder<'_>, deps: &D) -> Arc { // The last 16 bytes are the node count and edge count. debug!("position: {:?}", d.position()); - let (node_count, edge_count) = - d.with_position(d.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| { + + // `node_max` is the number of indices including empty nodes while `node_count` + // is the number of actually encoded nodes. + let (node_max, node_count, edge_count) = + d.with_position(d.len() - 3 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| { debug!("position: {:?}", d.position()); + let node_max = IntEncodedWithFixedSize::decode(d).0 as usize; let node_count = IntEncodedWithFixedSize::decode(d).0 as usize; let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize; - (node_count, edge_count) + (node_max, node_count, edge_count) }); debug!("position: {:?}", d.position()); debug!(?node_count, ?edge_count); - let graph_bytes = d.len() - (2 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position(); + let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position(); let mut nodes = IndexVec::from_elem_n( DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) }, - node_count, + node_max, ); - let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_count); + let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max); let mut edge_list_indices = - IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_count); + IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max); // This estimation assumes that all of the encoded bytes are for the edge lists or for the // fixed-size node headers. But that's not necessarily true; if any edge list has a length @@ -217,7 +228,7 @@ impl SerializedDepGraph { let mut edge_list_data = Vec::with_capacity(graph_bytes - node_count * size_of::>()); - for _index in 0..node_count { + for _ in 0..node_count { // Decode the header for this edge; the header packs together as many of the fixed-size // fields as possible to limit the number of times we update decoder state. let node_header = @@ -263,8 +274,8 @@ impl SerializedDepGraph { for (idx, node) in nodes.iter_enumerated() { if index[node.kind.as_usize()].insert(node.hash, idx).is_some() { - // Side effect nodes can have duplicates - if node.kind != D::DEP_KIND_SIDE_EFFECT { + // Empty nodes and side effect nodes can have duplicates + if node.kind != D::DEP_KIND_NULL && node.kind != D::DEP_KIND_SIDE_EFFECT { let name = deps.name(node.kind); panic!( "Error: A dep graph node ({name}) does not have an unique index. \ @@ -508,17 +519,32 @@ struct Stat { edge_counter: u64, } -struct EncoderState { - previous: Arc, - encoder: FileEncoder, - total_node_count: usize, - total_edge_count: usize, - stats: Option>, - - mem_encoder: MemEncoder, +struct LocalEncoderState { + next_node_index: u32, + remaining_node_index: u32, + encoder: MemEncoder, + node_count: usize, + edge_count: usize, /// Stores the number of times we've encoded each dep kind. kind_stats: Vec, +} + +struct LocalEncoderResult { + node_max: u32, + node_count: usize, + edge_count: usize, + + /// Stores the number of times we've encoded each dep kind. + kind_stats: Vec, +} + +struct EncoderState { + next_node_index: AtomicU64, + previous: Arc, + file: Lock>, + local: WorkerLocal>, + stats: Option>>, marker: PhantomData, } @@ -526,34 +552,58 @@ impl EncoderState { fn new(encoder: FileEncoder, record_stats: bool, previous: Arc) -> Self { Self { previous, - encoder, - total_edge_count: 0, - total_node_count: 0, - stats: record_stats.then(FxHashMap::default), - mem_encoder: MemEncoder::new(), - kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(), + next_node_index: AtomicU64::new(0), + stats: record_stats.then(|| Lock::new(FxHashMap::default())), + file: Lock::new(Some(encoder)), + local: WorkerLocal::new(|_| { + RefCell::new(LocalEncoderState { + next_node_index: 0, + remaining_node_index: 0, + edge_count: 0, + node_count: 0, + encoder: MemEncoder::new(), + kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(), + }) + }), marker: PhantomData, } } #[inline] - fn alloc_index(&mut self) -> DepNodeIndex { - let index = DepNodeIndex::new(self.total_node_count); - self.total_node_count += 1; - index + fn next_index(&self, local: &mut LocalEncoderState) -> DepNodeIndex { + if local.remaining_node_index == 0 { + let count = 256; + + // We assume that there won't be enough active threads to overflow u64 from u32::MAX here. + assert!(self.next_node_index.load(Ordering::Relaxed) <= u32::MAX as u64); + local.next_node_index = + self.next_node_index.fetch_add(count, Ordering::Relaxed).try_into().unwrap(); + + local.remaining_node_index = count as u32; + } + + DepNodeIndex::from_u32(local.next_node_index) + } + + #[inline] + fn bump_index(&self, local: &mut LocalEncoderState) { + local.remaining_node_index -= 1; + local.next_node_index += 1; + local.node_count += 1; } #[inline] fn record( - &mut self, + &self, node: DepNode, index: DepNodeIndex, edge_count: usize, - edges: impl FnOnce(&mut Self) -> Vec, + edges: impl FnOnce(&Self) -> Vec, record_graph: &Option>, - ) -> DepNodeIndex { - self.kind_stats[node.kind.as_usize()] += 1; - self.total_edge_count += edge_count; + local: &mut LocalEncoderState, + ) { + local.kind_stats[node.kind.as_usize()] += 1; + local.edge_count += edge_count; if let Some(record_graph) = &record_graph { // Call `edges` before the outlined code to allow the closure to be optimized out. @@ -568,40 +618,47 @@ impl EncoderState { }); } - if let Some(stats) = &mut self.stats { + if let Some(stats) = &self.stats { let kind = node.kind; // Outline the stats code as it's typically disabled and cold. outline(move || { + let mut stats = stats.lock(); let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 }); stat.node_counter += 1; stat.edge_counter += edge_count as u64; }); } - - index } #[inline] - fn flush_mem_encoder(&mut self) { - let data = &mut self.mem_encoder.data; + fn flush_mem_encoder(&self, local: &mut LocalEncoderState) { + let data = &mut local.encoder.data; if data.len() > 64 * 1024 { - self.encoder.emit_raw_bytes(&data[..]); + self.file.lock().as_mut().unwrap().emit_raw_bytes(&data[..]); data.clear(); } } /// Encodes a node to the current graph. fn encode_node( - &mut self, + &self, + index: DepNodeIndex, node: &NodeInfo, record_graph: &Option>, - ) -> DepNodeIndex { - let index = self.alloc_index(); - node.encode::(&mut self.mem_encoder, index); - self.flush_mem_encoder(); - self.record(node.node, index, node.edges.len(), |_| node.edges[..].to_vec(), record_graph) + local: &mut LocalEncoderState, + ) { + node.encode::(&mut local.encoder, index); + self.flush_mem_encoder(&mut *local); + self.record( + node.node, + index, + node.edges.len(), + |_| node.edges[..].to_vec(), + record_graph, + &mut *local, + ); } /// Encodes a node that was promoted from the previous graph. It reads the information directly from @@ -612,16 +669,17 @@ impl EncoderState { /// It expects all edges to already have a new dep node index assigned. #[inline] fn encode_promoted_node( - &mut self, + &self, + index: DepNodeIndex, prev_index: SerializedDepNodeIndex, record_graph: &Option>, colors: &DepNodeColorMap, - ) -> DepNodeIndex { - let index = self.alloc_index(); + local: &mut LocalEncoderState, + ) { let node = self.previous.index_to_node(prev_index); let fingerprint = self.previous.fingerprint_by_index(prev_index); let edge_count = NodeInfo::encode_promoted::( - &mut self.mem_encoder, + &mut local.encoder, node, index, fingerprint, @@ -629,7 +687,7 @@ impl EncoderState { colors, &self.previous, ); - self.flush_mem_encoder(); + self.flush_mem_encoder(&mut *local); self.record( node, index, @@ -641,38 +699,60 @@ impl EncoderState { .collect() }, record_graph, + &mut *local, ); - index } - fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult { - let Self { - mut encoder, - mem_encoder, - total_node_count, - total_edge_count, - stats: _, - kind_stats, - marker: _, - previous, - } = self; + fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph) -> FileEncodeResult { + // Prevent more indices from being allocated. + self.next_node_index.store(u32::MAX as u64 + 1, Ordering::SeqCst); - encoder.emit_raw_bytes(&mem_encoder.data); + let results = broadcast(|_| { + let mut local = self.local.borrow_mut(); - let node_count = total_node_count.try_into().unwrap(); - let edge_count = total_edge_count.try_into().unwrap(); + // Prevent more indices from being allocated on this thread. + local.remaining_node_index = 0; + + let data = mem::replace(&mut local.encoder.data, Vec::new()); + self.file.lock().as_mut().unwrap().emit_raw_bytes(&data); + + LocalEncoderResult { + kind_stats: local.kind_stats.clone(), + node_max: local.next_node_index, + node_count: local.node_count, + edge_count: local.edge_count, + } + }); + + let mut encoder = self.file.lock().take().unwrap(); + + let mut kind_stats: Vec = iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(); + + let mut node_max = 0; + let mut node_count = 0; + let mut edge_count = 0; + + for result in results { + node_max = max(node_max, result.node_max); + node_count += result.node_count; + edge_count += result.edge_count; + for (i, stat) in result.kind_stats.iter().enumerate() { + kind_stats[i] += stat; + } + } // Encode the number of each dep kind encountered for count in kind_stats.iter() { count.encode(&mut encoder); } - previous.session_count.checked_add(1).unwrap().encode(&mut encoder); + self.previous.session_count.checked_add(1).unwrap().encode(&mut encoder); - debug!(?node_count, ?edge_count); + debug!(?node_max, ?node_count, ?edge_count); debug!("position: {:?}", encoder.position()); - IntEncodedWithFixedSize(node_count).encode(&mut encoder); - IntEncodedWithFixedSize(edge_count).encode(&mut encoder); + IntEncodedWithFixedSize(node_max.try_into().unwrap()).encode(&mut encoder); + IntEncodedWithFixedSize(node_count.try_into().unwrap()).encode(&mut encoder); + IntEncodedWithFixedSize(edge_count.try_into().unwrap()).encode(&mut encoder); debug!("position: {:?}", encoder.position()); // Drop the encoder so that nothing is written after the counts. let result = encoder.finish(); @@ -681,44 +761,20 @@ impl EncoderState { // don't need a dependency on rustc_incremental just for that. profiler.artifact_size("dep_graph", "dep-graph.bin", position as u64); } + + self.print_incremental_info(current, node_count, edge_count); + result } -} -pub(crate) struct GraphEncoder { - profiler: SelfProfilerRef, - status: Lock>>, - record_graph: Option>, -} - -impl GraphEncoder { - pub(crate) fn new( - encoder: FileEncoder, - prev_node_count: usize, - record_graph: bool, - record_stats: bool, - profiler: &SelfProfilerRef, - previous: Arc, - ) -> Self { - let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count))); - let status = Lock::new(Some(EncoderState::new(encoder, record_stats, previous))); - GraphEncoder { status, record_graph, profiler: profiler.clone() } - } - - pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) { - if let Some(record_graph) = &self.record_graph { - f(&record_graph.lock()) - } - } - - pub(crate) fn print_incremental_info( + fn print_incremental_info( &self, - total_read_count: u64, - total_duplicate_read_count: u64, + current: &CurrentDepGraph, + total_node_count: usize, + total_edge_count: usize, ) { - let mut status = self.status.lock(); - let status = status.as_mut().unwrap(); - if let Some(record_stats) = &status.stats { + if let Some(record_stats) = &self.stats { + let record_stats = record_stats.lock(); let mut stats: Vec<_> = record_stats.values().collect(); stats.sort_by_key(|s| -(s.node_counter as i64)); @@ -730,10 +786,13 @@ impl GraphEncoder { eprintln!("[incremental] DepGraph Statistics"); eprintln!("{SEPARATOR}"); eprintln!("[incremental]"); - eprintln!("[incremental] Total Node Count: {}", status.total_node_count); - eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count); + eprintln!("[incremental] Total Node Count: {}", total_node_count); + eprintln!("[incremental] Total Edge Count: {}", total_edge_count); if cfg!(debug_assertions) { + let total_read_count = current.total_read_count.load(Ordering::Relaxed); + let total_duplicate_read_count = + current.total_duplicate_read_count.load(Ordering::Relaxed); eprintln!("[incremental] Total Edge Reads: {total_read_count}"); eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}"); } @@ -747,7 +806,7 @@ impl GraphEncoder { for stat in stats { let node_kind_ratio = - (100.0 * (stat.node_counter as f64)) / (status.total_node_count as f64); + (100.0 * (stat.node_counter as f64)) / (total_node_count as f64); let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64); eprintln!( @@ -763,6 +822,35 @@ impl GraphEncoder { eprintln!("[incremental]"); } } +} + +pub(crate) struct GraphEncoder { + profiler: SelfProfilerRef, + status: EncoderState, + record_graph: Option>, +} + +impl GraphEncoder { + pub(crate) fn new( + sess: &Session, + encoder: FileEncoder, + prev_node_count: usize, + previous: Arc, + ) -> Self { + let record_graph = sess + .opts + .unstable_opts + .query_dep_graph + .then(|| Lock::new(DepGraphQuery::new(prev_node_count))); + let status = EncoderState::new(encoder, sess.opts.unstable_opts.incremental_info, previous); + GraphEncoder { status, record_graph, profiler: sess.prof.clone() } + } + + pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) { + if let Some(record_graph) = &self.record_graph { + f(&record_graph.lock()) + } + } /// Encodes a node that does not exists in the previous graph. pub(crate) fn send_new( @@ -773,7 +861,11 @@ impl GraphEncoder { ) -> DepNodeIndex { let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph"); let node = NodeInfo { node, fingerprint, edges }; - self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph) + let mut local = self.status.local.borrow_mut(); + let index = self.status.next_index(&mut *local); + self.status.bump_index(&mut *local); + self.status.encode_node(index, &node, &self.record_graph, &mut *local); + index } /// Encodes a node that exists in the previous graph, but was re-executed. @@ -791,23 +883,24 @@ impl GraphEncoder { 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(); + let mut local = self.status.local.borrow_mut(); - // 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 + let index = self.status.next_index(&mut *local); + + if is_green { + // Use `try_mark_green` to avoid racing when `send_promoted` is called concurrently + // on the same index. + match colors.try_mark_green(prev_index, index) { + Ok(()) => (), + Err(dep_node_index) => return dep_node_index, } - Some(DepNodeColor::Green(dep_node_index)) => dep_node_index, - Some(DepNodeColor::Red) => panic!(), + } else { + colors.insert(prev_index, DepNodeColor::Red); } + + self.status.bump_index(&mut *local); + self.status.encode_node(index, &node, &self.record_graph, &mut *local); + index } /// Encodes a node that was promoted from the previous graph. It reads the information directly from @@ -822,26 +915,30 @@ impl GraphEncoder { ) -> DepNodeIndex { let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph"); - let mut status = self.status.lock(); - let status = status.as_mut().unwrap(); + let mut local = self.status.local.borrow_mut(); + let index = self.status.next_index(&mut *local); - // Check colors inside the lock to avoid racing when `send_promoted` or `send_and_color` + // Use `try_mark_green` 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 = - status.encode_promoted_node(prev_index, &self.record_graph, colors); - colors.insert(prev_index, DepNodeColor::Green(dep_node_index)); - dep_node_index + match colors.try_mark_green(prev_index, index) { + Ok(()) => { + self.status.bump_index(&mut *local); + self.status.encode_promoted_node( + index, + prev_index, + &self.record_graph, + colors, + &mut *local, + ); + index } - Some(DepNodeColor::Green(dep_node_index)) => dep_node_index, - Some(DepNodeColor::Red) => panic!(), + Err(dep_node_index) => dep_node_index, } } - pub(crate) fn finish(&self) -> FileEncodeResult { + pub(crate) fn finish(&self, current: &CurrentDepGraph) -> FileEncodeResult { let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish"); - self.status.lock().take().unwrap().finish(&self.profiler) + self.status.finish(&self.profiler, current) } } From c43a6f05d6cedbb6a191e0c307cd257665a342e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 22 Apr 2025 04:36:58 +0200 Subject: [PATCH 056/262] Add some comments --- compiler/rustc_query_system/src/dep_graph/graph.rs | 3 ++- compiler/rustc_query_system/src/dep_graph/serialized.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 180a2c9edf67..3ae56cef2c42 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1341,7 +1341,8 @@ impl DepNodeColorMap { } /// This tries to atomically mark a node green and assign `index` as the new - /// index. + /// index. This returns `Ok` if `index` gets assigned, otherwise it returns + /// the alreadly allocated index in `Err`. #[inline] pub(super) fn try_mark_green( &self, diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index e88d95b6b074..648823edb189 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -585,6 +585,7 @@ impl EncoderState { DepNodeIndex::from_u32(local.next_node_index) } + /// Marks the index previously returned by `next_index` as used. #[inline] fn bump_index(&self, local: &mut LocalEncoderState) { local.remaining_node_index -= 1; From 3e196c00c2374263d943b5e2226164d4c5f122db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 1 May 2025 11:41:42 +0200 Subject: [PATCH 057/262] remove a couple of clones --- .../hir-def/src/expr_store/lower/generics.rs | 2 +- .../crates/hir-expand/src/attrs.rs | 2 +- .../crates/hir-ty/src/dyn_compatibility.rs | 2 +- .../crates/hir-ty/src/infer/closure.rs | 2 +- .../crates/hir-ty/src/infer/expr.rs | 4 +-- .../crates/hir-ty/src/infer/pat.rs | 4 +-- .../crates/hir-ty/src/infer/unify.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 26 +++++--------- .../rust-analyzer/crates/hir/src/semantics.rs | 20 +++++------ .../crates/hir/src/semantics/source_to_def.rs | 2 +- .../crates/hir/src/source_analyzer.rs | 2 +- .../src/handlers/convert_bool_then.rs | 2 +- .../src/handlers/convert_from_to_tryfrom.rs | 2 +- .../src/handlers/generate_function.rs | 6 ++-- .../src/handlers/wrap_unwrap_cfg_attr.rs | 6 ++-- .../ide-completion/src/context/analysis.rs | 6 +--- .../crates/ide-db/src/items_locator.rs | 4 +-- .../src/handlers/type_mismatch.rs | 2 +- .../rust-analyzer/crates/intern/src/symbol.rs | 34 +++++++++---------- .../crates/load-cargo/src/lib.rs | 2 +- .../crates/project-model/src/env.rs | 2 +- .../crates/project-model/src/workspace.rs | 2 +- .../crates/query-group-macro/src/lib.rs | 2 +- .../src/cli/unresolved_references.rs | 2 +- .../crates/rust-analyzer/src/config.rs | 2 +- .../crates/rust-analyzer/src/global_state.rs | 2 +- .../src/handlers/notification.rs | 2 +- .../rust-analyzer/src/handlers/request.rs | 2 +- .../rust-analyzer/tests/slow-tests/ratoml.rs | 7 ++-- .../rust-analyzer/tests/slow-tests/support.rs | 2 +- .../syntax/src/syntax_editor/edit_algo.rs | 2 +- .../crates/test-fixture/src/lib.rs | 2 +- 32 files changed, 71 insertions(+), 90 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs index 42c85571f646..02a1d274fb5e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs @@ -270,7 +270,7 @@ impl GenericParamsCollector { let self_ = Name::new_symbol_root(sym::Self_); let idx = self.type_or_consts.alloc( TypeParamData { - name: Some(self_.clone()), + name: Some(self_), default: None, provenance: TypeParamProvenance::TraitSelf, } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 107316239809..bb17eb062760 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -320,7 +320,7 @@ impl Attr { ) -> impl IntoIterator { let is_cfg_attr = self.path.as_ident().is_some_and(|name| *name == sym::cfg_attr); if !is_cfg_attr { - return smallvec![self.clone()]; + return smallvec![self]; } let subtree = match self.token_tree_value() { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index fecaafb4c2e8..106b996b13ef 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -515,7 +515,7 @@ fn receiver_is_dispatchable( trait_id: to_chalk_trait_id(trait_), substitution: Substitution::from_iter( Interner, - std::iter::once(unsized_self_ty.clone().cast(Interner)) + std::iter::once(unsized_self_ty.cast(Interner)) .chain(placeholder_subst.iter(Interner).skip(1).cloned()), ), }); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index cf3b15d2a679..800897c6fc3a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -127,7 +127,7 @@ impl InferenceContext<'_> { let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); let prev_closure = mem::replace(&mut self.current_closure, id); let prev_ret_ty = mem::replace(&mut self.return_ty, body_ret_ty.clone()); - let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(body_ret_ty.clone())); + let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(body_ret_ty)); let prev_resume_yield_tys = mem::replace(&mut self.resume_yield_tys, resume_yield_tys); self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 5468254ab910..8084b394d044 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -827,9 +827,9 @@ impl InferenceContext<'_> { } let assoc = self.resolve_ops_index_output(); self.resolve_associated_type_with_params( - self_ty.clone(), + self_ty, assoc, - &[index_ty.clone().cast(Interner)], + &[index_ty.cast(Interner)], ) } else { self.err_ty() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index dc1de3b9e851..a9a3265858e4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -435,7 +435,7 @@ impl InferenceContext<'_> { decl: Option, ) -> Ty { let (expectation_type, expectation_lt) = match expected.as_reference() { - Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime.clone()), + Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime), None => { let inner_ty = self.table.new_type_var(); let inner_lt = self.table.new_lifetime_var(); @@ -597,7 +597,7 @@ impl InferenceContext<'_> { let size = consteval::usize_const(self.db, Some(len as u128), self.owner.krate(self.db)); let elem_ty = self.table.new_type_var(); - let array_ty = TyKind::Array(elem_ty.clone(), size).intern(Interner); + let array_ty = TyKind::Array(elem_ty, size).intern(Interner); Some(array_ty) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index d921afeb9879..631b571465fe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -1029,7 +1029,7 @@ impl<'a> InferenceTable<'a> { }; let sized_pred = WhereClause::Implemented(TraitRef { trait_id: to_chalk_trait_id(sized), - substitution: Substitution::from1(Interner, ty.clone()), + substitution: Substitution::from1(Interner, ty), }); let goal = GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(sized_pred)).intern(Interner); matches!(self.try_obligation(goal), Some(Solution::Unique(_))) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index d7754bf2e233..3f1d5bb01f2a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -3685,24 +3685,16 @@ impl GenericDef { } let source_map = match def { - GenericDefId::AdtId(AdtId::EnumId(it)) => { - db.enum_signature_with_source_map(it).1.clone() - } - GenericDefId::AdtId(AdtId::StructId(it)) => { - db.struct_signature_with_source_map(it).1.clone() - } - GenericDefId::AdtId(AdtId::UnionId(it)) => { - db.union_signature_with_source_map(it).1.clone() - } + GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature_with_source_map(it).1, + GenericDefId::AdtId(AdtId::StructId(it)) => db.struct_signature_with_source_map(it).1, + GenericDefId::AdtId(AdtId::UnionId(it)) => db.union_signature_with_source_map(it).1, GenericDefId::ConstId(_) => return, - GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1.clone(), - GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1.clone(), + GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1, + GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1, GenericDefId::StaticId(_) => return, - GenericDefId::TraitAliasId(it) => { - db.trait_alias_signature_with_source_map(it).1.clone() - } - GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1.clone(), - GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1.clone(), + GenericDefId::TraitAliasId(it) => db.trait_alias_signature_with_source_map(it).1, + GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1, + GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1, }; expr_store_diagnostics(db, acc, &source_map); @@ -3802,7 +3794,7 @@ impl GenericSubstitution { container_params .chain(self_params) .filter_map(|(ty, name)| { - Some((name?.symbol().clone(), Type { ty: ty.clone(), env: self.env.clone() })) + Some((name?.symbol().clone(), Type { ty, env: self.env.clone() })) }) .collect() } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 2e693559e292..4d092c1f0bb0 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -926,7 +926,7 @@ impl<'db> SemanticsImpl<'db> { token: InRealFile, mut cb: impl FnMut(InFile, SyntaxContext) -> ControlFlow, ) -> Option { - self.descend_into_macros_impl(token.clone(), &mut cb) + self.descend_into_macros_impl(token, &mut cb) } /// Descends the token into expansions, returning the tokens that matches the input @@ -958,17 +958,13 @@ impl<'db> SemanticsImpl<'db> { let text = token.text(); let kind = token.kind(); if let Ok(token) = self.wrap_token_infile(token.clone()).into_real_file() { - self.descend_into_macros_breakable( - token.clone(), - |InFile { value, file_id: _ }, _ctx| { - let mapped_kind = value.kind(); - let any_ident_match = - || kind.is_any_identifier() && value.kind().is_any_identifier(); - let matches = - (kind == mapped_kind || any_ident_match()) && text == value.text(); - if matches { ControlFlow::Break(value) } else { ControlFlow::Continue(()) } - }, - ) + self.descend_into_macros_breakable(token, |InFile { value, file_id: _ }, _ctx| { + let mapped_kind = value.kind(); + let any_ident_match = + || kind.is_any_identifier() && value.kind().is_any_identifier(); + let matches = (kind == mapped_kind || any_ident_match()) && text == value.text(); + if matches { ControlFlow::Break(value) } else { ControlFlow::Continue(()) } + }) } else { None } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 466bf7f6c826..587c51d8cc99 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -559,7 +559,7 @@ impl SourceToDefCtx<'_, '_> { let item = match ast::Item::cast(value.clone()) { Some(it) => it, None => { - let variant = ast::Variant::cast(value.clone())?; + let variant = ast::Variant::cast(value)?; return this .enum_variant_to_def(InFile::new(file_id, &variant)) .map(Into::into); diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 7d447116e088..c1a75ce7e574 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -1431,7 +1431,7 @@ impl SourceAnalyzer { } fn ty_of_expr(&self, expr: ast::Expr) -> Option<&Ty> { - self.infer()?.type_of_expr_or_pat(self.expr_id(expr.clone())?) + self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?) } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index cd23ad223729..bcd06c1ef725 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -196,7 +196,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> // Wrap all tails in `Some(...)` let none_path = mapless_make.expr_path(mapless_make.ident_path("None")); let some_path = mapless_make.expr_path(mapless_make.ident_path("Some")); - for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| { + for_each_tail_expr(&ast::Expr::BlockExpr(closure_body), &mut |e| { let e = match e { ast::Expr::BreakExpr(e) => e.expr(), ast::Expr::ReturnExpr(e) => e.expr(), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index 24cc32d10d88..db41927f1df2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -80,7 +80,7 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> let from_fn_name = builder.make_mut(from_fn_name); let tail_expr = builder.make_mut(tail_expr); let return_exprs = return_exprs.map(|r| builder.make_mut(r)).collect_vec(); - let associated_items = builder.make_mut(associated_items).clone(); + let associated_items = builder.make_mut(associated_items); ted::replace( trait_ty.syntax(), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index ba2b84a42c75..aac145a72150 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -392,14 +392,14 @@ impl FunctionBuilder { // Focus the return type if there is one match ret_type { Some(ret_type) => { - edit.add_placeholder_snippet(cap, ret_type.clone()); + edit.add_placeholder_snippet(cap, ret_type); } None => { - edit.add_placeholder_snippet(cap, tail_expr.clone()); + edit.add_placeholder_snippet(cap, tail_expr); } } } else { - edit.add_placeholder_snippet(cap, tail_expr.clone()); + edit.add_placeholder_snippet(cap, tail_expr); } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 1068d5d4cd57..e1b94673e775 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -116,7 +116,7 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - (Some(attr), Some(ident)) if attr.simple_name().map(|v| v.eq("derive")).unwrap_or_default() => { - Some(attempt_get_derive(attr.clone(), ident)) + Some(attempt_get_derive(attr, ident)) } (Some(attr), _) => Some(WrapUnwrapOption::WrapAttr(attr)), @@ -128,7 +128,7 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - NodeOrToken::Node(node) => ast::Attr::cast(node).map(WrapUnwrapOption::WrapAttr), NodeOrToken::Token(ident) if ident.kind() == syntax::T![ident] => { let attr = ident.parent_ancestors().find_map(ast::Attr::cast)?; - Some(attempt_get_derive(attr.clone(), ident)) + Some(attempt_get_derive(attr, ident)) } _ => None, } @@ -233,7 +233,7 @@ fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) -> if let Some(meta) = attr.meta() { if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) { raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" "))); - raw_tokens.push(NodeOrToken::Token(eq.clone())); + raw_tokens.push(NodeOrToken::Token(eq)); raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" "))); expr.syntax().descendants_with_tokens().for_each(|it| { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 822dae2578e7..391e2379dcd5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -387,11 +387,7 @@ fn expand( match ( sema.expand_macro_call(&actual_macro_call), - sema.speculative_expand_macro_call( - &actual_macro_call, - &speculative_args, - fake_ident_token.clone(), - ), + sema.speculative_expand_macro_call(&actual_macro_call, &speculative_args, fake_ident_token), ) { // successful expansions (Some(actual_expansion), Some((fake_expansion, fake_mapped_tokens))) => { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs index e9385253250a..4b0a84a559e2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs @@ -86,7 +86,7 @@ pub fn items_with_name_in_module( let local_query = match name { NameToImport::Prefix(exact_name, case_sensitive) | NameToImport::Exact(exact_name, case_sensitive) => { - let mut local_query = symbol_index::Query::new(exact_name.clone()); + let mut local_query = symbol_index::Query::new(exact_name); local_query.assoc_search_mode(assoc_item_search); if prefix { local_query.prefix(); @@ -99,7 +99,7 @@ pub fn items_with_name_in_module( local_query } NameToImport::Fuzzy(fuzzy_search_string, case_sensitive) => { - let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone()); + let mut local_query = symbol_index::Query::new(fuzzy_search_string); local_query.fuzzy(); local_query.assoc_search_mode(assoc_item_search); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 8f6ed1a7bdbd..1db9b6d04944 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -195,7 +195,7 @@ fn remove_unnecessary_wrapper( let db = ctx.sema.db; let root = db.parse_or_expand(expr_ptr.file_id); let expr = expr_ptr.value.to_node(&root); - let expr = ctx.sema.original_ast_node(expr.clone())?; + let expr = ctx.sema.original_ast_node(expr)?; let Expr::CallExpr(call_expr) = expr else { return None; diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 89c3be96fcb9..8b2d6e8717d2 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -163,28 +163,28 @@ impl Symbol { pub fn integer(i: usize) -> Self { match i { - 0 => symbols::INTEGER_0.clone(), - 1 => symbols::INTEGER_1.clone(), - 2 => symbols::INTEGER_2.clone(), - 3 => symbols::INTEGER_3.clone(), - 4 => symbols::INTEGER_4.clone(), - 5 => symbols::INTEGER_5.clone(), - 6 => symbols::INTEGER_6.clone(), - 7 => symbols::INTEGER_7.clone(), - 8 => symbols::INTEGER_8.clone(), - 9 => symbols::INTEGER_9.clone(), - 10 => symbols::INTEGER_10.clone(), - 11 => symbols::INTEGER_11.clone(), - 12 => symbols::INTEGER_12.clone(), - 13 => symbols::INTEGER_13.clone(), - 14 => symbols::INTEGER_14.clone(), - 15 => symbols::INTEGER_15.clone(), + 0 => symbols::INTEGER_0, + 1 => symbols::INTEGER_1, + 2 => symbols::INTEGER_2, + 3 => symbols::INTEGER_3, + 4 => symbols::INTEGER_4, + 5 => symbols::INTEGER_5, + 6 => symbols::INTEGER_6, + 7 => symbols::INTEGER_7, + 8 => symbols::INTEGER_8, + 9 => symbols::INTEGER_9, + 10 => symbols::INTEGER_10, + 11 => symbols::INTEGER_11, + 12 => symbols::INTEGER_12, + 13 => symbols::INTEGER_13, + 14 => symbols::INTEGER_14, + 15 => symbols::INTEGER_15, i => Symbol::intern(&format!("{i}")), } } pub fn empty() -> Self { - symbols::__empty.clone() + symbols::__empty } #[inline] diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 3e52dbaea654..2686a75c7c86 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -292,7 +292,7 @@ impl ProjectFolders { }; let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())]; - let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]); + let entry = vfs::loader::Entry::Files(vec![ratoml_path]); res.watch.push(res.load.len()); res.load.push(entry); diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs index f2e5df171ae3..e7293b0b2ef6 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/env.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs @@ -25,7 +25,7 @@ pub(crate) fn inject_cargo_package_env(env: &mut Env, package: &PackageData) { env.set("CARGO_PKG_VERSION_PATCH", package.version.patch.to_string()); env.set("CARGO_PKG_VERSION_PRE", package.version.pre.to_string()); - env.set("CARGO_PKG_AUTHORS", package.authors.join(":").clone()); + env.set("CARGO_PKG_AUTHORS", package.authors.join(":")); env.set("CARGO_PKG_NAME", package.name.clone()); env.set("CARGO_PKG_DESCRIPTION", package.description.as_deref().unwrap_or_default()); diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index c6e0cf36aff2..eec0077ea6e2 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1370,7 +1370,7 @@ fn detached_file_to_crate_graph( Edition::CURRENT, display_name.clone(), None, - cfg_options.clone(), + cfg_options, None, Env::default(), CrateOrigin::Local { diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs index 357e56ddfaa0..ec4b6b2a4ac3 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs @@ -210,7 +210,7 @@ pub(crate) fn query_group_impl( .into_iter() .filter(|fn_arg| matches!(fn_arg, FnArg::Typed(_))) .map(|fn_arg| match fn_arg { - FnArg::Typed(pat_type) => pat_type.clone(), + FnArg::Typed(pat_type) => pat_type, FnArg::Receiver(_) => unreachable!("this should have been filtered out"), }) .collect::>(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index 1d4fbb942235..0362e13b88b7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -30,7 +30,7 @@ impl flags::UnresolvedReferences { let root = vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize(); let config = crate::config::Config::new( - root.clone(), + root, lsp_types::ClientCapabilities::default(), vec![], None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 9acbcc08a9dd..03e5b1f6f4b6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1183,7 +1183,7 @@ impl ConfigChange { source_root_map: Arc>, ) { assert!(self.source_map_change.is_none()); - self.source_map_change = Some(source_root_map.clone()); + self.source_map_change = Some(source_root_map); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 820276e8aea2..3b3b9c879754 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -511,7 +511,7 @@ impl GlobalState { self.fetch_workspaces_queue.request_op( format!("workspace vfs file change: {path}"), - FetchWorkspaceRequest { path: Some(path.to_owned()), force_crate_graph_reload }, + FetchWorkspaceRequest { path: Some(path), force_crate_graph_reload }, ); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index a30e5d8ce268..b7373f274f05 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -309,7 +309,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { let task = move || -> std::result::Result<(), Cancelled> { if invocation_strategy_once { let saved_file = vfs_path.as_path().map(|p| p.to_owned()); - world.flycheck[0].restart_workspace(saved_file.clone()); + world.flycheck[0].restart_workspace(saved_file); } let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index e08dd80973a7..69983a676261 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -2210,7 +2210,7 @@ fn runnable_action_links( let label = update_test.label(); if let Some(r) = to_proto::make_update_runnable(&r, update_test) { let update_command = to_proto::command::run_single(&r, label.unwrap().as_str()); - group.commands.push(to_command_link(update_command, r.label.clone())); + group.commands.push(to_command_link(update_command, r.label)); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs index 3f313b7e57fe..485f32281dde 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs @@ -82,11 +82,8 @@ impl RatomlTest { } Url::parse( - format!( - "file://{}", - path.into_string().to_owned().replace("C:\\", "/c:/").replace('\\', "/") - ) - .as_str(), + format!("file://{}", path.into_string().replace("C:\\", "/c:/").replace('\\', "/")) + .as_str(), ) .unwrap() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index 7b5a53311217..2bebb0c1b970 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -202,7 +202,7 @@ impl Project<'_> { } let mut config = Config::new( - tmp_dir_path.clone(), + tmp_dir_path, lsp_types::ClientCapabilities { workspace: Some(lsp_types::WorkspaceClientCapabilities { did_change_watched_files: Some( diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs index 6a9c88b55d7e..01c1f0d49bfd 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs @@ -391,7 +391,7 @@ fn report_intersecting_changes( fn to_owning_node(element: &SyntaxElement) -> SyntaxNode { match element { SyntaxElement::Node(node) => node.clone(), - SyntaxElement::Token(token) => token.parent().unwrap().clone(), + SyntaxElement::Token(token) => token.parent().unwrap(), } } diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 2f379d419e8f..f6ca5ab6c8c5 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -353,7 +353,7 @@ impl ChangeFixture { )]), CrateOrigin::Local { repo: None, name: None }, true, - proc_macro_cwd.clone(), + proc_macro_cwd, crate_ws_data, ); proc_macros.insert(proc_macros_crate, Ok(proc_macro)); From 60218be5e997a9d6ced4857cc13cd9441d5c3e40 Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Thu, 1 May 2025 07:40:43 -0400 Subject: [PATCH 058/262] Remove backtrace dep from anyhow in features status dump tool According to `anyhow`'s Cargo.toml: > On compilers older than 1.65, features=["backtrace"] may be used to enable > backtraces via the `backtrace` crate. This feature has no effect on 1.65+ > besides bringing in an unused dependency, as `std::backtrace` is always > preferred. So this is just bringing in an unused dependency. --- Cargo.lock | 3 --- src/tools/features-status-dump/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60daa453c60d..b06119bc0920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,6 @@ name = "anyhow" version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" -dependencies = [ - "backtrace", -] [[package]] name = "ar_archive_writer" diff --git a/src/tools/features-status-dump/Cargo.toml b/src/tools/features-status-dump/Cargo.toml index 35be71a46e55..b2976f14a01a 100644 --- a/src/tools/features-status-dump/Cargo.toml +++ b/src/tools/features-status-dump/Cargo.toml @@ -5,7 +5,7 @@ license = "MIT OR Apache-2.0" edition = "2021" [dependencies] -anyhow = { version = "1", features = ["backtrace"] } +anyhow = { version = "1" } clap = { version = "4", features = ["derive"] } serde = { version = "1.0.125", features = [ "derive" ] } serde_json = "1.0.59" From bfe3d54d817cd66e4ab85d94409db8a572fdadd7 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 1 May 2025 13:11:53 +0100 Subject: [PATCH 059/262] User type annotations for free consts in pattern position --- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 3 +-- .../user_type_annotations_pattern.rs | 14 ++++++++++++++ .../user_type_annotations_pattern.stderr | 11 +++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tests/ui/generic-const-items/user_type_annotations_pattern.rs create mode 100644 tests/ui/generic-const-items/user_type_annotations_pattern.stderr diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 8e69ff568b92..4f00a85004d0 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -553,8 +553,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let res = self.typeck_results.qpath_res(qpath, id); let (def_id, user_ty) = match res { - Res::Def(DefKind::Const, def_id) => (def_id, None), - Res::Def(DefKind::AssocConst, def_id) => { + Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => { (def_id, self.typeck_results.user_provided_types().get(id)) } diff --git a/tests/ui/generic-const-items/user_type_annotations_pattern.rs b/tests/ui/generic-const-items/user_type_annotations_pattern.rs new file mode 100644 index 000000000000..aa3846df2bca --- /dev/null +++ b/tests/ui/generic-const-items/user_type_annotations_pattern.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_items)] +#![expect(incomplete_features)] + +const FOO<'a: 'static>: usize = 10; + +fn bar<'a>() { + match 10_usize { + FOO::<'a> => todo!(), + //~^ ERROR: lifetime may not live long enough + _ => todo!(), + } +} + +fn main() {} diff --git a/tests/ui/generic-const-items/user_type_annotations_pattern.stderr b/tests/ui/generic-const-items/user_type_annotations_pattern.stderr new file mode 100644 index 000000000000..e15be275d297 --- /dev/null +++ b/tests/ui/generic-const-items/user_type_annotations_pattern.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/user_type_annotations_pattern.rs:8:9 + | +LL | fn bar<'a>() { + | -- lifetime `'a` defined here +LL | match 10_usize { +LL | FOO::<'a> => todo!(), + | ^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + From 53e3907bcb5a4519a6558051476c3198aba2a12c Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 1 May 2025 14:29:10 +0100 Subject: [PATCH 060/262] No-op split into sub functions --- .../src/traits/normalize.rs | 326 +++++++++--------- 1 file changed, 162 insertions(+), 164 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 5f0acd46f86a..e08428f925c9 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -10,8 +10,8 @@ use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, - TypingMode, + self, AliasTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, + TypeVisitableExt, TypingMode, }; use tracing::{debug, instrument}; @@ -178,6 +178,163 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) } } + + fn normalize_trait_projection(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { + if !data.has_escaping_bound_vars() { + // When we don't have escaping bound vars we can normalize ambig aliases + // to inference variables (done in `normalize_projection_ty`). This would + // be wrong if there were escaping bound vars as even if we instantiated + // the bound vars with placeholders, we wouldn't be able to map them back + // after normalization succeeded. + // + // Also, as an optimization: when we don't have escaping bound vars, we don't + // need to replace them with placeholders (see branch below). + let data = data.fold_with(self); + let normalized_ty = project::normalize_projection_ty( + self.selcx, + self.param_env, + data, + self.cause.clone(), + self.depth, + self.obligations, + ); + debug!( + ?self.depth, + ?ty, + ?normalized_ty, + obligations.len = ?self.obligations.len(), + "AssocTypeNormalizer: normalized type" + ); + normalized_ty.expect_type() + } else { + // If there are escaping bound vars, we temporarily replace the + // bound vars with placeholders. Note though, that in the case + // that we still can't project for whatever reason (e.g. self + // type isn't known enough), we *can't* register an obligation + // and return an inference variable (since then that obligation + // would have bound vars and that's a can of worms). Instead, + // we just give up and fall back to pretending like we never tried! + // + // Note: this isn't necessarily the final approach here; we may + // want to figure out how to register obligations with escaping vars + // or handle this some other way. + + let infcx = self.selcx.infcx; + let (data, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); + let data = data.fold_with(self); + let normalized_ty = project::opt_normalize_projection_term( + self.selcx, + self.param_env, + data.into(), + self.cause.clone(), + self.depth, + self.obligations, + ) + .ok() + .flatten() + .map(|term| term.expect_type()) + .map(|normalized_ty| { + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + normalized_ty, + ) + }) + .unwrap_or_else(|| ty.super_fold_with(self)); + + debug!( + ?self.depth, + ?ty, + ?normalized_ty, + obligations.len = ?self.obligations.len(), + "AssocTypeNormalizer: normalized type" + ); + normalized_ty + } + } + + fn normalize_inherent_projection(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { + if !data.has_escaping_bound_vars() { + // This branch is *mostly* just an optimization: when we don't + // have escaping bound vars, we don't need to replace them with + // placeholders (see branch below). *Also*, we know that we can + // register an obligation to *later* project, since we know + // there won't be bound vars there. + + let data = data.fold_with(self); + + project::normalize_inherent_projection( + self.selcx, + self.param_env, + data, + self.cause.clone(), + self.depth, + self.obligations, + ) + } else { + let infcx = self.selcx.infcx; + let (data, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); + let data = data.fold_with(self); + let ty = project::normalize_inherent_projection( + self.selcx, + self.param_env, + data, + self.cause.clone(), + self.depth, + self.obligations, + ); + + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + ty, + ) + } + } + + fn normalize_free_alias(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { + let recursion_limit = self.cx().recursion_limit(); + if !recursion_limit.value_within_limit(self.depth) { + self.selcx.infcx.err_ctxt().report_overflow_error( + OverflowCause::DeeplyNormalize(data.into()), + self.cause.span, + false, + |diag| { + diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow); + }, + ); + } + + let infcx = self.selcx.infcx; + self.obligations.extend( + infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map( + |(mut predicate, span)| { + if data.has_escaping_bound_vars() { + (predicate, ..) = BoundVarReplacer::replace_bound_vars( + infcx, + &mut self.universes, + predicate, + ); + } + let mut cause = self.cause.clone(); + cause.map_code(|code| ObligationCauseCode::TypeAlias(code, span, data.def_id)); + Obligation::new(infcx.tcx, cause, self.param_env, predicate) + }, + ), + ); + self.depth += 1; + let res = infcx.tcx.type_of(data.def_id).instantiate(infcx.tcx, data.args).fold_with(self); + self.depth -= 1; + res + } } impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx> { @@ -258,168 +415,9 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } } } - - ty::Projection if !data.has_escaping_bound_vars() => { - // When we don't have escaping bound vars we can normalize ambig aliases - // to inference variables (done in `normalize_projection_ty`). This would - // be wrong if there were escaping bound vars as even if we instantiated - // the bound vars with placeholders, we wouldn't be able to map them back - // after normalization succeeded. - // - // Also, as an optimization: when we don't have escaping bound vars, we don't - // need to replace them with placeholders (see branch below). - let data = data.fold_with(self); - let normalized_ty = project::normalize_projection_ty( - self.selcx, - self.param_env, - data, - self.cause.clone(), - self.depth, - self.obligations, - ); - debug!( - ?self.depth, - ?ty, - ?normalized_ty, - obligations.len = ?self.obligations.len(), - "AssocTypeNormalizer: normalized type" - ); - normalized_ty.expect_type() - } - - ty::Projection => { - // If there are escaping bound vars, we temporarily replace the - // bound vars with placeholders. Note though, that in the case - // that we still can't project for whatever reason (e.g. self - // type isn't known enough), we *can't* register an obligation - // and return an inference variable (since then that obligation - // would have bound vars and that's a can of worms). Instead, - // we just give up and fall back to pretending like we never tried! - // - // Note: this isn't necessarily the final approach here; we may - // want to figure out how to register obligations with escaping vars - // or handle this some other way. - - let infcx = self.selcx.infcx; - let (data, mapped_regions, mapped_types, mapped_consts) = - BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - let data = data.fold_with(self); - let normalized_ty = project::opt_normalize_projection_term( - self.selcx, - self.param_env, - data.into(), - self.cause.clone(), - self.depth, - self.obligations, - ) - .ok() - .flatten() - .map(|term| term.expect_type()) - .map(|normalized_ty| { - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - normalized_ty, - ) - }) - .unwrap_or_else(|| ty.super_fold_with(self)); - - debug!( - ?self.depth, - ?ty, - ?normalized_ty, - obligations.len = ?self.obligations.len(), - "AssocTypeNormalizer: normalized type" - ); - normalized_ty - } - ty::Free => { - let recursion_limit = self.cx().recursion_limit(); - if !recursion_limit.value_within_limit(self.depth) { - self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data.into()), - self.cause.span, - false, - |diag| { - diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow); - }, - ); - } - - let infcx = self.selcx.infcx; - self.obligations.extend( - infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map( - |(mut predicate, span)| { - if data.has_escaping_bound_vars() { - (predicate, ..) = BoundVarReplacer::replace_bound_vars( - infcx, - &mut self.universes, - predicate, - ); - } - let mut cause = self.cause.clone(); - cause.map_code(|code| { - ObligationCauseCode::TypeAlias(code, span, data.def_id) - }); - Obligation::new(infcx.tcx, cause, self.param_env, predicate) - }, - ), - ); - self.depth += 1; - let res = infcx - .tcx - .type_of(data.def_id) - .instantiate(infcx.tcx, data.args) - .fold_with(self); - self.depth -= 1; - res - } - - ty::Inherent if !data.has_escaping_bound_vars() => { - // This branch is *mostly* just an optimization: when we don't - // have escaping bound vars, we don't need to replace them with - // placeholders (see branch below). *Also*, we know that we can - // register an obligation to *later* project, since we know - // there won't be bound vars there. - - let data = data.fold_with(self); - - project::normalize_inherent_projection( - self.selcx, - self.param_env, - data, - self.cause.clone(), - self.depth, - self.obligations, - ) - } - - ty::Inherent => { - let infcx = self.selcx.infcx; - let (data, mapped_regions, mapped_types, mapped_consts) = - BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - let data = data.fold_with(self); - let ty = project::normalize_inherent_projection( - self.selcx, - self.param_env, - data, - self.cause.clone(), - self.depth, - self.obligations, - ); - - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - ty, - ) - } + ty::Projection => self.normalize_trait_projection(data), + ty::Free => self.normalize_free_alias(data), + ty::Inherent => self.normalize_inherent_projection(data), } } From 951412e2f3cf2b27f9a22076b5cb77fb8ff5f259 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 1 May 2025 00:37:37 +0000 Subject: [PATCH 061/262] PassWrapper: adapt for llvm/llvm-project@f137c3d592e96330e450a8fd63ef7e8877fc1908 In LLVM 21 PR https://github.com/llvm/llvm-project/pull/130940 `TargetRegistry::createTargetMachine` was changed to take a `const Triple&` and has deprecated the old `StringRef` method. @rustbot label llvm-main --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index ebe8eb57f2cd..d4a05fbbbc5d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -512,8 +512,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( #endif } +#if LLVM_VERSION_GE(21, 0) + TargetMachine *TM = TheTarget->createTargetMachine(Trip, CPU, Feature, + Options, RM, CM, OptLevel); +#else TargetMachine *TM = TheTarget->createTargetMachine( Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel); +#endif return wrap(TM); } From 238d113b0726b9734ec42737cbc461d08520bf35 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 1 May 2025 13:26:23 +0100 Subject: [PATCH 062/262] Set groundwork for proper const normalization --- compiler/rustc_infer/src/infer/projection.rs | 25 ++- compiler/rustc_middle/src/ty/context.rs | 12 +- compiler/rustc_middle/src/ty/print/pretty.rs | 5 +- compiler/rustc_middle/src/ty/util.rs | 2 + .../rustc_mir_build/src/thir/pattern/mod.rs | 2 + .../src/solve/normalizes_to/free_alias.rs | 16 +- .../src/solve/normalizes_to/inherent.rs | 13 +- .../src/solve/normalizes_to/mod.rs | 10 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/normalize.rs | 194 ++++++++++-------- .../src/traits/project.rs | 166 +++++++++------ .../src/traits/select/confirmation.rs | 1 - .../rustc_trait_selection/src/traits/wf.rs | 20 +- .../src/normalize_projection_ty.rs | 14 +- compiler/rustc_type_ir/src/predicate.rs | 70 ++++++- compiler/rustc_type_ir/src/relate.rs | 2 + compiler/rustc_type_ir/src/ty_kind.rs | 22 -- .../cross_crate_predicate.stderr | 15 +- 18 files changed, 366 insertions(+), 225 deletions(-) diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 1bee9632110b..2a4f9db8963c 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -1,7 +1,8 @@ use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty; use super::InferCtxt; +use crate::infer::Term; use crate::traits::{Obligation, PredicateObligations}; impl<'tcx> InferCtxt<'tcx> { @@ -11,24 +12,32 @@ impl<'tcx> InferCtxt<'tcx> { /// of the given projection. This allows us to proceed with projections /// while they cannot be resolved yet due to missing information or /// simply due to the lack of access to the trait resolution machinery. - pub fn projection_ty_to_infer( + pub fn projection_term_to_infer( &self, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + alias_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, obligations: &mut PredicateObligations<'tcx>, - ) -> Ty<'tcx> { + ) -> Term<'tcx> { debug_assert!(!self.next_trait_solver()); - let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id)); + + let span = self.tcx.def_span(alias_term.def_id); + let infer_var = if alias_term.kind(self.tcx).is_type() { + self.next_ty_var(span).into() + } else { + self.next_const_var(span).into() + }; + let projection = ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_term: projection_ty.into(), - term: ty_var.into(), + projection_term: alias_term, + term: infer_var, })); let obligation = Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection); obligations.push(obligation); - ty_var + + infer_var } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3ea285d3d8eb..0f7f8527088c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -243,10 +243,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ty::AliasTermKind::ProjectionTy } } + DefKind::AssocConst => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::AliasTermKind::InherentConst + } else { + ty::AliasTermKind::ProjectionConst + } + } DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, DefKind::TyAlias => ty::AliasTermKind::FreeTy, - DefKind::AssocConst => ty::AliasTermKind::ProjectionConst, - DefKind::AnonConst | DefKind::Const | DefKind::Ctor(_, CtorKind::Const) => { + DefKind::Const => ty::AliasTermKind::FreeConst, + DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => { ty::AliasTermKind::UnevaluatedConst } kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ad8677f7c7da..af90c2fb95da 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3195,7 +3195,7 @@ define_print! { ty::AliasTerm<'tcx> { match self.kind(cx.tcx()) { - ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)), + ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => p!(pretty_print_inherent_projection(*self)), ty::AliasTermKind::ProjectionTy => { if !(cx.should_print_verbose() || with_reduced_queries()) && cx.tcx().is_impl_trait_in_trait(self.def_id) @@ -3205,7 +3205,8 @@ define_print! { p!(print_def_path(self.def_id, self.args)); } } - | ty::AliasTermKind::FreeTy + ty::AliasTermKind::FreeTy + | ty::AliasTermKind::FreeConst | ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index f5158edffcff..6fe5927c29fc 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -966,7 +966,9 @@ impl<'tcx> TyCtxt<'tcx> { } ty::AliasTermKind::OpaqueTy => Some(self.variances_of(def_id)), ty::AliasTermKind::InherentTy + | ty::AliasTermKind::InherentConst | ty::AliasTermKind::FreeTy + | ty::AliasTermKind::FreeConst | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => None, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 8e69ff568b92..4a7e98f24ae3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -568,6 +568,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // Lower the named constant to a THIR pattern. let args = self.typeck_results.node_args(id); + // FIXME(mgca): we will need to special case IACs here to have type system compatible + // generic args, instead of how we represent them in body expressions. let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); let mut pattern = self.const_to_pat(c, ty, id, span); diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs index d077f8a9be8a..8aa6e4a3d711 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -19,19 +19,25 @@ where goal: Goal>, ) -> QueryResult { let cx = self.cx(); - let free_ty = goal.predicate.alias; + let free_alias = goal.predicate.alias; // Check where clauses self.add_goals( GoalSource::Misc, - cx.predicates_of(free_ty.def_id) - .iter_instantiated(cx, free_ty.args) + cx.predicates_of(free_alias.def_id) + .iter_instantiated(cx, free_alias.args) .map(|pred| goal.with(cx, pred)), ); - let actual = cx.type_of(free_ty.def_id).instantiate(cx, free_ty.args); - self.instantiate_normalizes_to_term(goal, actual.into()); + let actual = if free_alias.kind(cx).is_type() { + cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args) + } else { + // FIXME(mgca): once const items are actual aliases defined as equal to type system consts + // this should instead return that. + panic!("normalizing free const aliases in the type system is unsupported"); + }; + self.instantiate_normalizes_to_term(goal, actual.into()); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 1d1ff09ee410..2640238f5a90 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -15,12 +15,12 @@ where D: SolverDelegate, I: Interner, { - pub(super) fn normalize_inherent_associated_type( + pub(super) fn normalize_inherent_associated_term( &mut self, goal: Goal>, ) -> QueryResult { let cx = self.cx(); - let inherent = goal.predicate.alias.expect_ty(cx); + let inherent = goal.predicate.alias; let impl_def_id = cx.parent(inherent.def_id); let impl_args = self.fresh_args_for_item(impl_def_id); @@ -48,8 +48,13 @@ where .map(|pred| goal.with(cx, pred)), ); - let normalized = cx.type_of(inherent.def_id).instantiate(cx, inherent_args); - self.instantiate_normalizes_to_term(goal, normalized.into()); + let normalized = if inherent.kind(cx).is_type() { + cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into() + } else { + // FIXME(mgca): Properly handle IACs in the type system + panic!("normalizing inherent associated consts in the type system is unsupported"); + }; + self.instantiate_normalizes_to_term(goal, normalized); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } 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 b030af483817..400b4ce1200c 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 @@ -48,9 +48,13 @@ where }) }) } - ty::AliasTermKind::InherentTy => self.normalize_inherent_associated_type(goal), + ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => { + self.normalize_inherent_associated_term(goal) + } ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal), - ty::AliasTermKind::FreeTy => self.normalize_free_alias(goal), + ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => { + self.normalize_free_alias(goal) + } ty::AliasTermKind::UnevaluatedConst => self.normalize_anon_const(goal), } } @@ -333,6 +337,8 @@ where cx.type_of(target_item_def_id).map_bound(|ty| ty.into()) } ty::AliasTermKind::ProjectionConst => { + // FIXME(mgca): once const items are actual aliases defined as equal to type system consts + // this should instead return that. if cx.features().associated_const_equality() { panic!("associated const projection is not supported yet") } else { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0987c5b42d88..5b938456e03b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -51,7 +51,7 @@ pub use self::dyn_compatibility::{ pub use self::engine::{ObligationCtxt, TraitEngineExt}; pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation}; pub use self::normalize::NormalizeExt; -pub use self::project::{normalize_inherent_projection, normalize_projection_ty}; +pub use self::project::{normalize_inherent_projection, normalize_projection_term}; pub use self::select::{ EvaluationCache, EvaluationResult, IntercrateAmbiguityCause, OverflowError, SelectionCache, SelectionContext, diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index e08428f925c9..88a0c402702e 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,6 +1,7 @@ //! Deeply normalize types using the old trait solver. use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_hir::def::DefKind; use rustc_infer::infer::at::At; use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::{ @@ -10,15 +11,12 @@ use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ - self, AliasTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, + self, AliasTerm, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingMode, }; use tracing::{debug, instrument}; -use super::{ - BoundVarReplacer, PlaceholderReplacer, SelectionContext, project, - with_replaced_escaping_bound_vars, -}; +use super::{BoundVarReplacer, PlaceholderReplacer, SelectionContext, project}; use crate::error_reporting::InferCtxtErrorExt; use crate::error_reporting::traits::OverflowCause; use crate::solve::NextSolverError; @@ -179,8 +177,10 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) } } - fn normalize_trait_projection(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { - if !data.has_escaping_bound_vars() { + // FIXME(mgca): While this supports constants, it is only used for types by default right now + #[instrument(level = "debug", skip(self), ret)] + fn normalize_trait_projection(&mut self, proj: AliasTerm<'tcx>) -> Term<'tcx> { + if !proj.has_escaping_bound_vars() { // When we don't have escaping bound vars we can normalize ambig aliases // to inference variables (done in `normalize_projection_ty`). This would // be wrong if there were escaping bound vars as even if we instantiated @@ -189,23 +189,15 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { // // Also, as an optimization: when we don't have escaping bound vars, we don't // need to replace them with placeholders (see branch below). - let data = data.fold_with(self); - let normalized_ty = project::normalize_projection_ty( + let proj = proj.fold_with(self); + project::normalize_projection_term( self.selcx, self.param_env, - data, + proj, self.cause.clone(), self.depth, self.obligations, - ); - debug!( - ?self.depth, - ?ty, - ?normalized_ty, - obligations.len = ?self.obligations.len(), - "AssocTypeNormalizer: normalized type" - ); - normalized_ty.expect_type() + ) } else { // If there are escaping bound vars, we temporarily replace the // bound vars with placeholders. Note though, that in the case @@ -218,72 +210,64 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { // Note: this isn't necessarily the final approach here; we may // want to figure out how to register obligations with escaping vars // or handle this some other way. - let infcx = self.selcx.infcx; - let (data, mapped_regions, mapped_types, mapped_consts) = - BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - let data = data.fold_with(self); - let normalized_ty = project::opt_normalize_projection_term( + let (proj, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, proj); + let proj = proj.fold_with(self); + let normalized_term = project::opt_normalize_projection_term( self.selcx, self.param_env, - data.into(), + proj, self.cause.clone(), self.depth, self.obligations, ) .ok() .flatten() - .map(|term| term.expect_type()) - .map(|normalized_ty| { - PlaceholderReplacer::replace_placeholders( - infcx, - mapped_regions, - mapped_types, - mapped_consts, - &self.universes, - normalized_ty, - ) - }) - .unwrap_or_else(|| ty.super_fold_with(self)); + .unwrap_or(proj.to_term(infcx.tcx)); - debug!( - ?self.depth, - ?ty, - ?normalized_ty, - obligations.len = ?self.obligations.len(), - "AssocTypeNormalizer: normalized type" - ); - normalized_ty + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + normalized_term, + ) } } - fn normalize_inherent_projection(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { - if !data.has_escaping_bound_vars() { - // This branch is *mostly* just an optimization: when we don't - // have escaping bound vars, we don't need to replace them with - // placeholders (see branch below). *Also*, we know that we can - // register an obligation to *later* project, since we know - // there won't be bound vars there. - - let data = data.fold_with(self); + // FIXME(mgca): While this supports constants, it is only used for types by default right now + #[instrument(level = "debug", skip(self), ret)] + fn normalize_inherent_projection(&mut self, inherent: AliasTerm<'tcx>) -> Term<'tcx> { + if !inherent.has_escaping_bound_vars() { + // When we don't have escaping bound vars we can normalize ambig aliases + // to inference variables (done in `normalize_projection_ty`). This would + // be wrong if there were escaping bound vars as even if we instantiated + // the bound vars with placeholders, we wouldn't be able to map them back + // after normalization succeeded. + // + // Also, as an optimization: when we don't have escaping bound vars, we don't + // need to replace them with placeholders (see branch below). + let inherent = inherent.fold_with(self); project::normalize_inherent_projection( self.selcx, self.param_env, - data, + inherent, self.cause.clone(), self.depth, self.obligations, ) } else { let infcx = self.selcx.infcx; - let (data, mapped_regions, mapped_types, mapped_consts) = - BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); - let data = data.fold_with(self); - let ty = project::normalize_inherent_projection( + let (inherent, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, inherent); + let inherent = inherent.fold_with(self); + let inherent = project::normalize_inherent_projection( self.selcx, self.param_env, - data, + inherent, self.cause.clone(), self.depth, self.obligations, @@ -295,16 +279,18 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { mapped_types, mapped_consts, &self.universes, - ty, + inherent, ) } } - fn normalize_free_alias(&mut self, data: AliasTy<'tcx>) -> Ty<'tcx> { + // FIXME(mgca): While this supports constants, it is only used for types by default right now + #[instrument(level = "debug", skip(self), ret)] + fn normalize_free_alias(&mut self, free: AliasTerm<'tcx>) -> Term<'tcx> { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data.into()), + OverflowCause::DeeplyNormalize(free.into()), self.cause.span, false, |diag| { @@ -315,9 +301,13 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { let infcx = self.selcx.infcx; self.obligations.extend( - infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map( + // FIXME(BoxyUwU): + // FIXME(lazy_type_alias): + // It seems suspicious to instantiate the predicates with arguments that might be bound vars, + // we might wind up instantiating one of these bound vars underneath a hrtb. + infcx.tcx.predicates_of(free.def_id).instantiate_own(infcx.tcx, free.args).map( |(mut predicate, span)| { - if data.has_escaping_bound_vars() { + if free.has_escaping_bound_vars() { (predicate, ..) = BoundVarReplacer::replace_bound_vars( infcx, &mut self.universes, @@ -325,13 +315,21 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { ); } let mut cause = self.cause.clone(); - cause.map_code(|code| ObligationCauseCode::TypeAlias(code, span, data.def_id)); + cause.map_code(|code| ObligationCauseCode::TypeAlias(code, span, free.def_id)); Obligation::new(infcx.tcx, cause, self.param_env, predicate) }, ), ); self.depth += 1; - let res = infcx.tcx.type_of(data.def_id).instantiate(infcx.tcx, data.args).fold_with(self); + let res = if free.kind(infcx.tcx).is_type() { + infcx.tcx.type_of(free.def_id).instantiate(infcx.tcx, free.args).fold_with(self).into() + } else { + // FIXME(mgca): once const items are actual aliases defined as equal to type system consts + // this should instead use that rather than evaluating. + super::evaluate_const(infcx, free.to_term(infcx.tcx).expect_const(), self.param_env) + .super_fold_with(self) + .into() + }; self.depth -= 1; res } @@ -415,28 +413,64 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } } } - ty::Projection => self.normalize_trait_projection(data), - ty::Free => self.normalize_free_alias(data), - ty::Inherent => self.normalize_inherent_projection(data), + + ty::Projection => self.normalize_trait_projection(data.into()).expect_type(), + ty::Inherent => self.normalize_inherent_projection(data.into()).expect_type(), + ty::Free => self.normalize_free_alias(data.into()).expect_type(), } } #[instrument(skip(self), level = "debug")] - fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); - if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant) - { - constant + if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &ct) { + return ct; + } + + // Doing "proper" normalization of const aliases is inherently cyclic until const items + // are real aliases instead of having bodies. We gate proper const alias handling behind + // mgca to avoid breaking stable code, though this should become the "main" codepath long + // before mgca is stabilized. + // + // FIXME(BoxyUwU): Enabling this by default is blocked on a refactoring to how const items + // are represented. + if tcx.features().min_generic_const_args() { + let uv = match ct.kind() { + ty::ConstKind::Unevaluated(uv) => uv, + _ => return ct.super_fold_with(self), + }; + + let ct = match tcx.def_kind(uv.def) { + DefKind::AssocConst => match tcx.def_kind(tcx.parent(uv.def)) { + DefKind::Trait => self.normalize_trait_projection(uv.into()), + DefKind::Impl { of_trait: false } => { + self.normalize_inherent_projection(uv.into()) + } + kind => unreachable!( + "unexpected `DefKind` for const alias' resolution's parent def: {:?}", + kind + ), + }, + DefKind::Const | DefKind::AnonConst => self.normalize_free_alias(uv.into()), + kind => { + unreachable!("unexpected `DefKind` for const alias to resolve to: {:?}", kind) + } + }; + + // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be + // unnormalized after const evaluation returns. + ct.expect_const().super_fold_with(self) } else { - let constant = constant.super_fold_with(self); - debug!(?constant, ?self.param_env); - with_replaced_escaping_bound_vars( + let ct = ct.super_fold_with(self); + return super::with_replaced_escaping_bound_vars( self.selcx.infcx, &mut self.universes, - constant, - |constant| super::evaluate_const(self.selcx.infcx, constant, self.param_env), + ct, + |ct| super::evaluate_const(self.selcx.infcx, ct, self.param_env), ) - .super_fold_with(self) + .super_fold_with(self); + // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be + // unnormalized after const evaluation returns. } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index dd868c9d40ea..ca58da5ca6d5 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -5,7 +5,6 @@ use std::ops::ControlFlow; use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; @@ -172,6 +171,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// ``` /// If successful, this may result in additional obligations. Also returns /// the projection cache key used to track these additional obligations. +// FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "debug", skip(selcx))] pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, @@ -201,6 +201,7 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( /// If successful, this may result in additional obligations. /// /// See [poly_project_and_unify_term] for an explanation of the return value. +// FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "debug", skip(selcx))] fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, @@ -258,34 +259,28 @@ fn project_and_unify_term<'cx, 'tcx>( /// there are unresolved type variables in the projection, we will /// instantiate it with a fresh type variable `$X` and generate a new /// obligation `::Item == $X` for later. -pub fn normalize_projection_ty<'a, 'b, 'tcx>( +// FIXME(mgca): While this supports constants, it is only used for types by default right now +pub fn normalize_projection_term<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + alias_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut PredicateObligations<'tcx>, ) -> Term<'tcx> { - opt_normalize_projection_term( - selcx, - param_env, - projection_ty.into(), - cause.clone(), - depth, - obligations, - ) - .ok() - .flatten() - .unwrap_or_else(move || { - // if we bottom out in ambiguity, create a type variable - // and a deferred predicate to resolve this when more type - // information is available. + opt_normalize_projection_term(selcx, param_env, alias_term, cause.clone(), depth, obligations) + .ok() + .flatten() + .unwrap_or_else(move || { + // if we bottom out in ambiguity, create a type variable + // and a deferred predicate to resolve this when more type + // information is available. - selcx - .infcx - .projection_ty_to_infer(param_env, projection_ty, cause, depth + 1, obligations) - .into() - }) + selcx + .infcx + .projection_term_to_infer(param_env, alias_term, cause, depth + 1, obligations) + .into() + }) } /// The guts of `normalize`: normalize a specific projection like `( /// often immediately appended to another obligations vector. So now this /// function takes an obligations vector and appends to it directly, which is /// slightly uglier but avoids the need for an extra short-lived allocation. +// FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, @@ -456,6 +452,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( /// an error for this obligation, but we legitimately should not, /// because it contains `[type error]`. Yuck! (See issue #29857 for /// one case where this arose.) +// FIXME(mgca): While this supports constants, it is only used for types by default right now fn normalize_to_error<'a, 'tcx>( selcx: &SelectionContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -469,9 +466,10 @@ fn normalize_to_error<'a, 'tcx>( | ty::AliasTermKind::InherentTy | ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::FreeTy => selcx.infcx.next_ty_var(cause.span).into(), - ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { - selcx.infcx.next_const_var(cause.span).into() - } + ty::AliasTermKind::FreeConst + | ty::AliasTermKind::InherentConst + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => selcx.infcx.next_const_var(cause.span).into(), }; let mut obligations = PredicateObligations::new(); obligations.push(Obligation { @@ -484,36 +482,37 @@ fn normalize_to_error<'a, 'tcx>( } /// Confirm and normalize the given inherent projection. +// FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] pub fn normalize_inherent_projection<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, - alias_ty: ty::AliasTy<'tcx>, + alias_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut PredicateObligations<'tcx>, -) -> Ty<'tcx> { +) -> ty::Term<'tcx> { let tcx = selcx.tcx(); if !tcx.recursion_limit().value_within_limit(depth) { // Halt compilation because it is important that overflows never be masked. tcx.dcx().emit_fatal(InherentProjectionNormalizationOverflow { span: cause.span, - ty: alias_ty.to_string(), + ty: alias_term.to_string(), }); } - let args = compute_inherent_assoc_ty_args( + let args = compute_inherent_assoc_term_args( selcx, param_env, - alias_ty, + alias_term, cause.clone(), depth, obligations, ); // Register the obligations arising from the impl and from the associated type itself. - let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, args); + let predicates = tcx.predicates_of(alias_term.def_id).instantiate(tcx, args); for (predicate, span) in predicates { let predicate = normalize_with_depth_to( selcx, @@ -531,7 +530,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. // Consider creating separate cause codes for this specific situation. - ObligationCauseCode::WhereClause(alias_ty.def_id, span), + ObligationCauseCode::WhereClause(alias_term.def_id, span), ); obligations.push(Obligation::with_depth( @@ -543,27 +542,33 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( )); } - let ty = tcx.type_of(alias_ty.def_id).instantiate(tcx, args); + let term: Term<'tcx> = if alias_term.kind(tcx).is_type() { + tcx.type_of(alias_term.def_id).instantiate(tcx, args).into() + } else { + get_associated_const_value(selcx, alias_term.to_term(tcx).expect_const(), param_env).into() + }; - let mut ty = selcx.infcx.resolve_vars_if_possible(ty); - if ty.has_aliases() { - ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations); + let mut term = selcx.infcx.resolve_vars_if_possible(term); + if term.has_aliases() { + term = + normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, term, obligations); } - ty + term } -pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( +// FIXME(mgca): While this supports constants, it is only used for types by default right now +pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, - alias_ty: ty::AliasTy<'tcx>, + alias_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut PredicateObligations<'tcx>, ) -> ty::GenericArgsRef<'tcx> { let tcx = selcx.tcx(); - let impl_def_id = tcx.parent(alias_ty.def_id); + let impl_def_id = tcx.parent(alias_term.def_id); let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id); let mut impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args); @@ -580,7 +585,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( // Infer the generic parameters of the impl by unifying the // impl type with the self type of the projection. - let mut self_ty = alias_ty.self_ty(); + let mut self_ty = alias_term.self_ty(); if !selcx.infcx.next_trait_solver() { self_ty = normalize_with_depth_to( selcx, @@ -602,7 +607,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( } } - alias_ty.rebase_inherent_args_onto_impl(impl_args, tcx) + alias_term.rebase_inherent_args_onto_impl(impl_args, tcx) } enum Projected<'tcx> { @@ -630,6 +635,7 @@ impl<'tcx> Progress<'tcx> { /// /// IMPORTANT: /// - `obligation` must be fully normalized +// FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "info", skip(selcx))] fn project<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, @@ -896,7 +902,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( ImplSource::UserDefined(impl_data) => { // We have to be careful when projecting out of an // impl because of specialization. If we are not in - // codegen (i.e., projection mode is not "any"), and the + // codegen (i.e., `TypingMode` is not `PostAnalysis`), and the // impl's type is declared as default, then we disable // projection (even if the trait ref is fully // monomorphic). In the case where trait ref is not @@ -1189,6 +1195,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( }); } +// FIXME(mgca): While this supports constants, it is only used for types by default right now fn confirm_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, @@ -1222,6 +1229,7 @@ fn confirm_candidate<'cx, 'tcx>( result } +// FIXME(mgca): While this supports constants, it is only used for types by default right now fn confirm_select_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, @@ -1873,6 +1881,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( .with_addl_obligations(nested) } +// FIXME(mgca): While this supports constants, it is only used for types by default right now fn confirm_param_env_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, @@ -1926,9 +1935,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( ) { Ok(InferOk { value: _, obligations }) => { nested_obligations.extend(obligations); - assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations); - // FIXME(associated_const_equality): Handle consts here as well? Maybe this progress type should just take - // a term instead. + assoc_term_own_obligations(selcx, obligation, &mut nested_obligations); Progress { term: cache_entry.term, obligations: nested_obligations } } Err(e) => { @@ -1942,6 +1949,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( } } +// FIXME(mgca): While this supports constants, it is only used for types by default right now fn confirm_impl_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, @@ -1955,8 +1963,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); 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, + let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) { + Ok(assoc_term) => assoc_term, Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))), }; @@ -1965,10 +1973,10 @@ fn confirm_impl_candidate<'cx, 'tcx>( // has impossible-to-satisfy predicates (since those were // allowed in ), // or because the impl is literally missing the definition. - if !assoc_ty.item.defaultness(tcx).has_value() { + if !assoc_term.item.defaultness(tcx).has_value() { debug!( "confirm_impl_candidate: no associated type {:?} for {:?}", - assoc_ty.item.name(), + assoc_term.item.name(), obligation.predicate ); if tcx.impl_self_is_guaranteed_unsized(impl_def_id) { @@ -1979,7 +1987,11 @@ fn confirm_impl_candidate<'cx, 'tcx>( return Ok(Projected::NoProgress(obligation.predicate.to_term(tcx))); } else { return Ok(Projected::Progress(Progress { - term: Ty::new_misc_error(tcx).into(), + term: if obligation.predicate.kind(tcx).is_type() { + Ty::new_misc_error(tcx).into() + } else { + ty::Const::new_misc_error(tcx).into() + }, obligations: nested, })); } @@ -1992,27 +2004,32 @@ fn confirm_impl_candidate<'cx, 'tcx>( // * `args` is `[u32]` // * `args` ends up as `[u32, S]` 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 args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_term.defining_node); - 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); - let uv = ty::UnevaluatedConst::new(did, identity_args); - ty::EarlyBinder::bind(ty::Const::new_unevaluated(tcx, uv).into()) + let term = if obligation.predicate.kind(tcx).is_type() { + tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into()) } else { - tcx.type_of(assoc_ty.item.def_id).map_bound(|ty| ty.into()) + ty::EarlyBinder::bind( + get_associated_const_value( + selcx, + obligation.predicate.to_term(tcx).expect_const(), + param_env, + ) + .into(), + ) }; - let progress = if !tcx.check_args_compatible(assoc_ty.item.def_id, args) { - let err = Ty::new_error_with_message( - tcx, - obligation.cause.span, - "impl item and trait item have different parameters", - ); - Progress { term: err.into(), obligations: nested } + let progress = if !tcx.check_args_compatible(assoc_term.item.def_id, args) { + let msg = "impl item and trait item have different parameters"; + let span = obligation.cause.span; + let err = if obligation.predicate.kind(tcx).is_type() { + Ty::new_error_with_message(tcx, span, msg).into() + } else { + ty::Const::new_error_with_message(tcx, span, msg).into() + }; + Progress { term: err, obligations: nested } } else { - assoc_ty_own_obligations(selcx, obligation, &mut nested); + assoc_term_own_obligations(selcx, obligation, &mut nested); Progress { term: term.instantiate(tcx, args), obligations: nested } }; Ok(Projected::Progress(progress)) @@ -2020,7 +2037,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( // Get obligations corresponding to the predicates from the where-clause of the // associated type itself. -fn assoc_ty_own_obligations<'cx, 'tcx>( +// FIXME(mgca): While this supports constants, it is only used for types by default right now +fn assoc_term_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, nested: &mut PredicateObligations<'tcx>, @@ -2090,3 +2108,15 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> { }) } } + +fn get_associated_const_value<'tcx>( + selcx: &mut SelectionContext<'_, 'tcx>, + alias_ct: ty::Const<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> ty::Const<'tcx> { + // FIXME(mgca): We shouldn't be invoking ctfe here, instead const items should be aliases to type + // system consts that we can retrieve with some `query const_arg_of_alias` query. Evaluating the + // constant is "close enough" to getting the actual rhs of the const item for now even if it might + // lead to some cycles + super::evaluate_const(selcx.infcx, alias_ct, param_env) +} diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8008c7e4d342..94190cd3ae33 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -406,7 +406,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let mut assume = predicate.trait_ref.args.const_at(2); - // FIXME(mgca): We should shallowly normalize this. if self.tcx().features().generic_const_exprs() { assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 2e32cda7602e..08d3b92e9b5e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -6,6 +6,7 @@ use std::iter; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::bug; @@ -486,7 +487,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an inherent alias to be WF /// into `self.out`. // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`. - fn add_wf_preds_for_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) { + fn add_wf_preds_for_inherent_projection(&mut self, data: ty::AliasTerm<'tcx>) { // An inherent projection is well-formed if // // (a) its predicates hold (*) @@ -498,7 +499,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { if !data.self_ty().has_escaping_bound_vars() { // FIXME(inherent_associated_types): Should this happen inside of a snapshot? // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm! - let args = traits::project::compute_inherent_assoc_ty_args( + let args = traits::project::compute_inherent_assoc_term_args( &mut traits::SelectionContext::new(self.infcx), self.param_env, data, @@ -776,7 +777,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { self.out.extend(obligations); } ty::Alias(ty::Inherent, data) => { - self.add_wf_preds_for_inherent_projection(data); + self.add_wf_preds_for_inherent_projection(data.into()); return; // Subtree handled by compute_inherent_projection. } @@ -961,9 +962,6 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { match c.kind() { ty::ConstKind::Unevaluated(uv) => { if !c.has_escaping_bound_vars() { - let obligations = self.nominal_obligations(uv.def, uv.args); - self.out.extend(obligations); - let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::ConstEvaluatable(c), )); @@ -975,6 +973,16 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { self.param_env, predicate, )); + + if tcx.def_kind(uv.def) == DefKind::AssocConst + && tcx.def_kind(tcx.parent(uv.def)) == (DefKind::Impl { of_trait: false }) + { + self.add_wf_preds_for_inherent_projection(uv.into()); + return; // Subtree is handled by above function + } else { + let obligations = self.nominal_obligations(uv.def, uv.args); + self.out.extend(obligations); + } } } ty::ConstKind::Infer(_) => { diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 14a92ebb9f96..e52898cc6e24 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -32,8 +32,14 @@ fn normalize_canonicalized_projection_ty<'tcx>( let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = PredicateObligations::new(); - let answer = - traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations); + let answer = traits::normalize_projection_term( + selcx, + param_env, + goal.into(), + cause, + 0, + &mut obligations, + ); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that // are recursive (given some generic parameters of the opaque's type variables). @@ -104,14 +110,14 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( let answer = traits::normalize_inherent_projection( selcx, param_env, - goal, + goal.into(), cause, 0, &mut obligations, ); ocx.register_obligations(obligations); - Ok(NormalizationResult { normalized_ty: answer }) + Ok(NormalizationResult { normalized_ty: answer.expect_type() }) }, ) } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 0411c5c2325e..b59495b93c83 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -474,10 +474,15 @@ pub enum AliasTermKind { /// Currently only used if the type alias references opaque types. /// Can always be normalized away. FreeTy, - /// An unevaluated const coming from a generic const expression. + + /// An unevaluated anonymous constants. UnevaluatedConst, /// An unevaluated const coming from an associated const. ProjectionConst, + /// A top level const item not part of a trait or impl. + FreeConst, + /// An associated const in an inherent `impl` + InherentConst, } impl AliasTermKind { @@ -486,11 +491,27 @@ impl AliasTermKind { AliasTermKind::ProjectionTy => "associated type", AliasTermKind::ProjectionConst => "associated const", AliasTermKind::InherentTy => "inherent associated type", + AliasTermKind::InherentConst => "inherent associated const", AliasTermKind::OpaqueTy => "opaque type", AliasTermKind::FreeTy => "type alias", + AliasTermKind::FreeConst => "unevaluated constant", AliasTermKind::UnevaluatedConst => "unevaluated constant", } } + + pub fn is_type(self) -> bool { + match self { + AliasTermKind::ProjectionTy + | AliasTermKind::InherentTy + | AliasTermKind::OpaqueTy + | AliasTermKind::FreeTy => true, + + AliasTermKind::UnevaluatedConst + | AliasTermKind::ProjectionConst + | AliasTermKind::InherentConst + | AliasTermKind::FreeConst => false, + } + } } impl From for AliasTermKind { @@ -566,7 +587,10 @@ impl AliasTerm { | AliasTermKind::InherentTy | AliasTermKind::OpaqueTy | AliasTermKind::FreeTy => {} - AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => { + AliasTermKind::InherentConst + | AliasTermKind::FreeConst + | AliasTermKind::UnevaluatedConst + | AliasTermKind::ProjectionConst => { panic!("Cannot turn `UnevaluatedConst` into `AliasTy`") } } @@ -603,18 +627,19 @@ impl AliasTerm { ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, ) .into(), - AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => { - I::Const::new_unevaluated( - interner, - ty::UnevaluatedConst::new(self.def_id, self.args), - ) - .into() - } + AliasTermKind::FreeConst + | AliasTermKind::InherentConst + | AliasTermKind::UnevaluatedConst + | AliasTermKind::ProjectionConst => I::Const::new_unevaluated( + interner, + ty::UnevaluatedConst::new(self.def_id, self.args), + ) + .into(), } } } -/// The following methods work only with (trait) associated type projections. +/// The following methods work only with (trait) associated term projections. impl AliasTerm { pub fn self_ty(self) -> I::Ty { self.args.type_at(0) @@ -659,6 +684,31 @@ impl AliasTerm { } } +/// The following methods work only with inherent associated term projections. +impl AliasTerm { + /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. + /// + /// Does the following transformation: + /// + /// ```text + /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] + /// + /// I_i impl args + /// P_j GAT args + /// ``` + pub fn rebase_inherent_args_onto_impl( + self, + impl_args: I::GenericArgs, + interner: I, + ) -> I::GenericArgs { + debug_assert!(matches!( + self.kind(interner), + AliasTermKind::InherentTy | AliasTermKind::InherentConst + )); + interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) + } +} + impl From> for AliasTerm { fn from(ty: ty::AliasTy) -> Self { AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () } diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index c80a567117c6..e3c4a793b37f 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -273,8 +273,10 @@ impl Relate for ty::AliasTerm { false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::FreeConst | ty::AliasTermKind::FreeTy | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::InherentConst | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { relate_args_invariantly(relation, a.args, b.args)? diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 21adbffc0274..cf2e4284d10d 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -514,28 +514,6 @@ impl AliasTy { } } -/// The following methods work only with inherent associated type projections. -impl AliasTy { - /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. - /// - /// Does the following transformation: - /// - /// ```text - /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] - /// - /// I_i impl args - /// P_j GAT args - /// ``` - pub fn rebase_inherent_args_onto_impl( - self, - impl_args: I::GenericArgs, - interner: I, - ) -> I::GenericArgs { - debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent); - interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) - } -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr( feature = "nightly", diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr index a05aaf2af649..1aac357d60e4 100644 --- a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr +++ b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr @@ -39,14 +39,6 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: required by a bound in `test1` - --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10 - | -LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] - | ----- required by a bound in this function -LL | where -LL | [u8; std::mem::size_of::() - 1]: Sized, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1` help: try adding a `where` bound | LL | fn user() where [(); std::mem::size_of::() - 1]: { @@ -59,10 +51,13 @@ LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `test1` - --> $DIR/auxiliary/const_evaluatable_lib.rs:3:27 + --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1` + | ----- required by a bound in this function +LL | where +LL | [u8; std::mem::size_of::() - 1]: Sized, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1` help: try adding a `where` bound | LL | fn user() where [(); std::mem::size_of::() - 1]: { From 9ec8373ab6beaf06425c5caa0fb783e767cdc6ad Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 1 May 2025 17:12:40 +0100 Subject: [PATCH 063/262] Crashes tests --- tests/crashes/127643.rs | 22 +++++++++++----------- tests/crashes/133066.rs | 12 ------------ 2 files changed, 11 insertions(+), 23 deletions(-) delete mode 100644 tests/crashes/133066.rs diff --git a/tests/crashes/127643.rs b/tests/crashes/127643.rs index a4db9397bdef..b5ec58b70e93 100644 --- a/tests/crashes/127643.rs +++ b/tests/crashes/127643.rs @@ -1,18 +1,18 @@ //@ known-bug: #127643 -#![feature(associated_const_equality)] +#![feature(generic_const_items, associated_const_equality)] +#![expect(incomplete_features)] -fn user() -> impl Owner {} - -trait Owner { - const C: K; -} -impl Owner for () { - const C: K = K::DEFAULT; +trait Foo { + const ASSOC: u32; } -trait ConstDefault { - const DEFAULT: Self; +impl Foo for () { + const ASSOC: u32 = N; } -fn main() {} +fn bar = { N }>>() {} + +fn main() { + bar::<10_u64, ()>(); +} diff --git a/tests/crashes/133066.rs b/tests/crashes/133066.rs deleted file mode 100644 index 732ebb7079fd..000000000000 --- a/tests/crashes/133066.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #133066 -trait Owner { - const C: u32; -} - -impl Owner for () {;} - -fn take0(_: impl Owner = { N }>) {} - -fn main() { - take0::(()); -} From 17d74d63208c9ac1dbbe2462edad667fbeb9469a Mon Sep 17 00:00:00 2001 From: Eyal Kalderon Date: Thu, 1 May 2025 15:13:43 -0400 Subject: [PATCH 064/262] Use present indicative tense in std::io::pipe() API docs The inline documentation for all other free functions in the `std::io` module use the phrase "creates a" instead of "create a", except for the currently nightly-only `std::io::pipe()` function. This commit updates the text to align with the predominant wording in the `std::io` module. I recognize this PR is quite a minuscule nitpick, so feel free to ignore and close if you disagree and/or there are bigger fish to fry. :smile: --- library/std/src/io/pipe.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index c6b7b49a351e..47243806cd2d 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -2,7 +2,7 @@ use crate::io; use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; use crate::sys_common::{FromInner, IntoInner}; -/// Create an anonymous pipe. +/// Creates an anonymous pipe. /// /// # Behavior /// @@ -108,7 +108,7 @@ impl IntoInner for PipeWriter { } impl PipeReader { - /// Create a new [`PipeReader`] instance that shares the same underlying file description. + /// Creates a new [`PipeReader`] instance that shares the same underlying file description. /// /// # Examples /// @@ -167,7 +167,7 @@ impl PipeReader { } impl PipeWriter { - /// Create a new [`PipeWriter`] instance that shares the same underlying file description. + /// Creates a new [`PipeWriter`] instance that shares the same underlying file description. /// /// # Examples /// From 042a556d8d0247361ed97e5d9217bb477c487be3 Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Thu, 3 Apr 2025 17:25:46 -0700 Subject: [PATCH 065/262] Change signature of File::try_lock and File::try_lock_shared These methods now return Result<(), TryLockError> instead of Result to make their use less errorprone --- library/std/src/fs.rs | 66 +++++++++++++++++++++++---- library/std/src/fs/tests.rs | 36 +++++++++++---- library/std/src/sys/fs/hermit.rs | 11 +++-- library/std/src/sys/fs/solid.rs | 11 +++-- library/std/src/sys/fs/uefi.rs | 5 +- library/std/src/sys/fs/unix.rs | 39 ++++++++++------ library/std/src/sys/fs/unsupported.rs | 5 +- library/std/src/sys/fs/wasi.rs | 11 +++-- library/std/src/sys/fs/windows.rs | 17 +++---- 9 files changed, 140 insertions(+), 61 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 801baf3d9907..27f60ffb00c8 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -116,6 +116,22 @@ pub struct File { inner: fs_imp::File, } +/// An enumeration of possible errors which can occur while trying to acquire a lock +/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`]. +/// +/// [`try_lock`]: File::try_lock +/// [`try_lock_shared`]: File::try_lock_shared +#[unstable(feature = "file_lock", issue = "130994")] +pub enum TryLockError { + /// The lock could not be acquired due to an I/O error on the file. The standard library will + /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`] + /// + /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock + Error(io::Error), + /// The lock could not be acquired at this time because it is held by another handle/process. + WouldBlock, +} + /// Metadata information about a file. /// /// This structure is returned from the [`metadata`] or @@ -352,6 +368,27 @@ pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result inner(path.as_ref(), contents.as_ref()) } +#[unstable(feature = "file_lock", issue = "130994")] +impl fmt::Debug for TryLockError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TryLockError::Error(err) => err.fmt(f), + TryLockError::WouldBlock => "WouldBlock".fmt(f), + } + } +} + +#[unstable(feature = "file_lock", issue = "130994")] +impl fmt::Display for TryLockError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TryLockError::Error(_) => "lock acquisition failed due to I/O error", + TryLockError::WouldBlock => "lock acquisition failed because the operation would block", + } + .fmt(f) + } +} + impl File { /// Attempts to open a file in read-only mode. /// @@ -734,8 +771,8 @@ impl File { /// Try to acquire an exclusive lock on the file. /// - /// Returns `Ok(false)` if a different lock is already held on this file (via another - /// handle/descriptor). + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file + /// (via another handle/descriptor). /// /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. /// @@ -777,23 +814,27 @@ impl File { /// /// ```no_run /// #![feature(file_lock)] - /// use std::fs::File; + /// use std::fs::{File, TryLockError}; /// /// fn main() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; - /// f.try_lock()?; + /// match f.try_lock() { + /// Ok(_) => (), + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired + /// Err(TryLockError::Error(err)) => return Err(err), + /// } /// Ok(()) /// } /// ``` #[unstable(feature = "file_lock", issue = "130994")] - pub fn try_lock(&self) -> io::Result { + pub fn try_lock(&self) -> Result<(), TryLockError> { self.inner.try_lock() } /// Try to acquire a shared (non-exclusive) lock on the file. /// - /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another - /// handle/descriptor). + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file + /// (via another handle/descriptor). /// /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may /// hold an exclusive lock at the same time. @@ -834,16 +875,21 @@ impl File { /// /// ```no_run /// #![feature(file_lock)] - /// use std::fs::File; + /// use std::fs::{File, TryLockError}; /// /// fn main() -> std::io::Result<()> { /// let f = File::open("foo.txt")?; - /// f.try_lock_shared()?; + /// match f.try_lock_shared() { + /// Ok(_) => (), + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired + /// Err(TryLockError::Error(err)) => return Err(err), + /// } + /// /// Ok(()) /// } /// ``` #[unstable(feature = "file_lock", issue = "130994")] - pub fn try_lock_shared(&self) -> io::Result { + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { self.inner.try_lock_shared() } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 4712e58980cc..46b0d832fec4 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1,6 +1,22 @@ use rand::RngCore; +#[cfg(any( + windows, + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_vendor = "apple", +))] +use crate::assert_matches::assert_matches; use crate::char::MAX_LEN_UTF8; +#[cfg(any( + windows, + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_vendor = "apple", +))] +use crate::fs::TryLockError; use crate::fs::{self, File, FileTimes, OpenOptions}; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; @@ -223,8 +239,8 @@ fn file_lock_multiple_shared() { check!(f2.lock_shared()); check!(f1.unlock()); check!(f2.unlock()); - assert!(check!(f1.try_lock_shared())); - assert!(check!(f2.try_lock_shared())); + check!(f1.try_lock_shared()); + check!(f2.try_lock_shared()); } #[test] @@ -243,12 +259,12 @@ fn file_lock_blocking() { // Check that shared locks block exclusive locks check!(f1.lock_shared()); - assert!(!check!(f2.try_lock())); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); check!(f1.unlock()); // Check that exclusive locks block shared locks check!(f1.lock()); - assert!(!check!(f2.try_lock_shared())); + assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock)); } #[test] @@ -267,9 +283,9 @@ fn file_lock_drop() { // Check that locks are released when the File is dropped check!(f1.lock_shared()); - assert!(!check!(f2.try_lock())); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); drop(f1); - assert!(check!(f2.try_lock())); + check!(f2.try_lock()); } #[test] @@ -288,10 +304,10 @@ fn file_lock_dup() { // Check that locks are not dropped if the File has been cloned check!(f1.lock_shared()); - assert!(!check!(f2.try_lock())); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); let cloned = check!(f1.try_clone()); drop(f1); - assert!(!check!(f2.try_lock())); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); drop(cloned) } @@ -307,9 +323,9 @@ fn file_lock_double_unlock() { // Check that both are released by unlock() check!(f1.lock()); check!(f1.lock_shared()); - assert!(!check!(f2.try_lock())); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); check!(f1.unlock()); - assert!(check!(f2.try_lock())); + check!(f2.try_lock()); } #[test] diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index f83a2f90ed22..d5412b2dda53 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -1,4 +1,5 @@ use crate::ffi::{CStr, OsStr, OsString, c_char}; +use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; use crate::os::hermit::ffi::OsStringExt; use crate::os::hermit::hermit_abi::{ @@ -12,7 +13,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr; pub use crate::sys::fs::common::{copy, exists}; use crate::sys::pal::fd::FileDesc; use crate::sys::time::SystemTime; -use crate::sys::{cvt, unsupported}; +use crate::sys::{cvt, unsupported, unsupported_err}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{fmt, mem}; @@ -366,12 +367,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> io::Result { - unsupported() + pub fn try_lock(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } - pub fn try_lock_shared(&self) -> io::Result { - unsupported() + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index 39de933b7248..3bfb39bac95b 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -2,6 +2,7 @@ use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; +use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::MaybeUninit; use crate::os::raw::{c_int, c_short}; @@ -11,7 +12,7 @@ use crate::sync::Arc; pub use crate::sys::fs::common::exists; use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; -use crate::sys::unsupported; +use crate::sys::{unsupported, unsupported_err}; use crate::sys_common::ignore_notfound; type CIntNotMinusOne = core::num::niche_types::NotAllOnes; @@ -352,12 +353,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> io::Result { - unsupported() + pub fn try_lock(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } - pub fn try_lock_shared(&self) -> io::Result { - unsupported() + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index d6ae86bd3d26..416c90b98b6d 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -2,6 +2,7 @@ use r_efi::protocols::file; use crate::ffi::OsString; use crate::fmt; +use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; @@ -227,11 +228,11 @@ impl File { self.0 } - pub fn try_lock(&self) -> io::Result { + pub fn try_lock(&self) -> Result<(), TryLockError> { self.0 } - pub fn try_lock_shared(&self) -> io::Result { + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { self.0 } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 87865be0387d..9f27542849f6 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -74,6 +74,7 @@ use libc::{dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, st use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt::{self, Write as _}; +use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; use crate::os::unix::prelude::*; @@ -1307,15 +1308,17 @@ impl File { target_os = "netbsd", target_vendor = "apple", ))] - pub fn try_lock(&self) -> io::Result { + pub fn try_lock(&self) -> Result<(), TryLockError> { let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }); - if let Err(ref err) = result { + if let Err(err) = result { if err.kind() == io::ErrorKind::WouldBlock { - return Ok(false); + Err(TryLockError::WouldBlock) + } else { + Err(TryLockError::Error(err)) } + } else { + Ok(()) } - result?; - return Ok(true); } #[cfg(not(any( @@ -1325,8 +1328,11 @@ impl File { target_os = "netbsd", target_vendor = "apple", )))] - pub fn try_lock(&self) -> io::Result { - Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) + pub fn try_lock(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(io::const_error!( + io::ErrorKind::Unsupported, + "try_lock() not supported" + ))) } #[cfg(any( @@ -1336,15 +1342,17 @@ impl File { target_os = "netbsd", target_vendor = "apple", ))] - pub fn try_lock_shared(&self) -> io::Result { + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) }); - if let Err(ref err) = result { + if let Err(err) = result { if err.kind() == io::ErrorKind::WouldBlock { - return Ok(false); + Err(TryLockError::WouldBlock) + } else { + Err(TryLockError::Error(err)) } + } else { + Ok(()) } - result?; - return Ok(true); } #[cfg(not(any( @@ -1354,8 +1362,11 @@ impl File { target_os = "netbsd", target_vendor = "apple", )))] - pub fn try_lock_shared(&self) -> io::Result { - Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(io::const_error!( + io::ErrorKind::Unsupported, + "try_lock_shared() not supported" + ))) } #[cfg(any( diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index 45e93deffa3a..0ff9533c0473 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -1,5 +1,6 @@ use crate::ffi::OsString; use crate::fmt; +use crate::fs::TryLockError; use crate::hash::{Hash, Hasher}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; @@ -206,11 +207,11 @@ impl File { self.0 } - pub fn try_lock(&self) -> io::Result { + pub fn try_lock(&self) -> Result<(), TryLockError> { self.0 } - pub fn try_lock_shared(&self) -> io::Result { + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { self.0 } diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs index 773040571bc9..ebfc7377a2ea 100644 --- a/library/std/src/sys/fs/wasi.rs +++ b/library/std/src/sys/fs/wasi.rs @@ -1,4 +1,5 @@ use crate::ffi::{CStr, OsStr, OsString}; +use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, ManuallyDrop}; use crate::os::raw::c_int; @@ -10,7 +11,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::WasiFd; pub use crate::sys::fs::common::exists; use crate::sys::time::SystemTime; -use crate::sys::unsupported; +use crate::sys::{unsupported, unsupported_err}; use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound}; use crate::{fmt, iter, ptr}; @@ -461,12 +462,12 @@ impl File { unsupported() } - pub fn try_lock(&self) -> io::Result { - unsupported() + pub fn try_lock(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } - pub fn try_lock_shared(&self) -> io::Result { - unsupported() + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + Err(TryLockError::Error(unsupported_err())) } pub fn unlock(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 15727c996837..6e54153325fb 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -3,6 +3,7 @@ use crate::alloc::{Layout, alloc, dealloc}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; +use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, MaybeUninit, offset_of}; use crate::os::windows::io::{AsHandle, BorrowedHandle}; @@ -397,7 +398,7 @@ impl File { self.acquire_lock(0) } - pub fn try_lock(&self) -> io::Result { + pub fn try_lock(&self) -> Result<(), TryLockError> { let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -411,18 +412,18 @@ impl File { }); match result { - Ok(_) => Ok(true), + Ok(_) => Ok(()), Err(err) if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { - Ok(false) + Err(TryLockError::WouldBlock) } - Err(err) => Err(err), + Err(err) => Err(TryLockError::Error(err)), } } - pub fn try_lock_shared(&self) -> io::Result { + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -436,14 +437,14 @@ impl File { }); match result { - Ok(_) => Ok(true), + Ok(_) => Ok(()), Err(err) if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { - Ok(false) + Err(TryLockError::WouldBlock) } - Err(err) => Err(err), + Err(err) => Err(TryLockError::Error(err)), } } From 1d11ee2a5b84693ac37173b4515e5411e76cad82 Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Sun, 6 Apr 2025 08:39:10 -0700 Subject: [PATCH 066/262] Implement error::Error for TryLockError --- library/std/src/fs.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 27f60ffb00c8..a1d4354d4fd4 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -21,7 +21,6 @@ mod tests; use crate::ffi::OsString; -use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; use crate::path::{Path, PathBuf}; use crate::sealed::Sealed; @@ -29,6 +28,7 @@ use crate::sync::Arc; use crate::sys::fs as fs_imp; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::time::SystemTime; +use crate::{error, fmt}; /// An object providing access to an open file on the filesystem. /// @@ -368,6 +368,9 @@ pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result inner(path.as_ref(), contents.as_ref()) } +#[unstable(feature = "file_lock", issue = "130994")] +impl error::Error for TryLockError {} + #[unstable(feature = "file_lock", issue = "130994")] impl fmt::Debug for TryLockError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { From 6970813e78a1d0f4298859471aaafece5e674a33 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Thu, 1 May 2025 18:40:38 +0200 Subject: [PATCH 067/262] Use less rustc_type_ir in the compiler codebase This commit does the following: - Replaces use of rustc_type_ir by rustc_middle in rustc_infer. - The DelayedMap type is exposed by rustc_middle so everything can be accessed through rustc_middle in a coherent manner. - API-layer traits, like InferCtxtLike, Interner or inherent::* must be accessed via rustc_type_ir, not rustc_middle::ty. For this reason these are not reexported by rustc_middle::ty. - Replaces use of ty::Interner by rustc_type_ir::Interner in rustc_trait_selection --- Cargo.lock | 1 + compiler/rustc_infer/src/infer/context.rs | 26 +++++++------------ .../src/infer/outlives/obligations.rs | 2 +- .../rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_infer/src/infer/relate/mod.rs | 5 ++-- .../src/infer/relate/type_relating.rs | 3 +-- compiler/rustc_infer/src/infer/resolve.rs | 3 +-- .../rustc_infer/src/infer/snapshot/fudge.rs | 3 +-- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 10 ++++++- compiler/rustc_trait_selection/Cargo.toml | 1 + .../src/solve/delegate.rs | 6 ++--- 12 files changed, 31 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 361d237b3af8..60daa453c60d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4494,6 +4494,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_transmute", + "rustc_type_ir", "smallvec", "thin-vec", "tracing", diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 75affa139770..22d7ce79bb46 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -121,19 +121,19 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.enter_forall(value, f) } - fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) { + fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) { self.inner.borrow_mut().type_variables().equate(a, b); } - fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) { + fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) { self.inner.borrow_mut().int_unification_table().union(a, b); } - fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) { + fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) { self.inner.borrow_mut().float_unification_table().union(a, b); } - fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) { + fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) { self.inner.borrow_mut().const_unification_table().union(a, b); } @@ -141,8 +141,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { &self, relation: &mut R, target_is_expected: bool, - target_vid: rustc_type_ir::TyVid, - instantiation_variance: rustc_type_ir::Variance, + target_vid: ty::TyVid, + instantiation_variance: ty::Variance, source_ty: Ty<'tcx>, ) -> RelateResult<'tcx, ()> { self.instantiate_ty_var( @@ -154,19 +154,11 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { ) } - fn instantiate_int_var_raw( - &self, - vid: rustc_type_ir::IntVid, - value: rustc_type_ir::IntVarValue, - ) { + fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) { self.inner.borrow_mut().int_unification_table().union_value(vid, value); } - fn instantiate_float_var_raw( - &self, - vid: rustc_type_ir::FloatVid, - value: rustc_type_ir::FloatVarValue, - ) { + fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) { self.inner.borrow_mut().float_unification_table().union_value(vid, value); } @@ -174,7 +166,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { &self, relation: &mut R, target_is_expected: bool, - target_vid: rustc_type_ir::ConstVid, + target_vid: ty::ConstVid, source_ct: ty::Const<'tcx>, ) -> RelateResult<'tcx, ()> { self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct) diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index a89cef50c9b4..8dde99c45cfa 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -63,11 +63,11 @@ use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::bug; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::NoSolution; +use rustc_middle::ty::outlives::{Component, push_outlives_components}; use rustc_middle::ty::{ self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesPredicate, Region, Ty, TyCtxt, TypeFoldable as _, TypeVisitableExt, }; -use rustc_type_ir::outlives::{Component, push_outlives_components}; use smallvec::smallvec; use tracing::{debug, instrument}; diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index c14c288c6e4e..69feecfe30a4 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,7 +1,7 @@ use std::assert_matches::assert_matches; +use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive}; use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; -use rustc_type_ir::outlives::{Component, compute_alias_components_recursive}; use smallvec::smallvec; use tracing::{debug, instrument, trace}; diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs index e6d1003cab61..6d25dfeb8593 100644 --- a/compiler/rustc_infer/src/infer/relate/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/mod.rs @@ -2,9 +2,8 @@ //! (except for some relations used for diagnostics and heuristics in the compiler). //! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc). -pub use rustc_middle::ty::relate::RelateResult; -pub use rustc_type_ir::relate::combine::PredicateEmittingRelation; -pub use rustc_type_ir::relate::*; +pub use rustc_middle::ty::relate::combine::PredicateEmittingRelation; +pub use rustc_middle::ty::relate::{RelateResult, *}; mod generalize; mod higher_ranked; diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 009271a8378f..04ff776594e6 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -3,9 +3,8 @@ use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys} use rustc_middle::ty::relate::{ Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances, }; -use rustc_middle::ty::{self, Ty, TyCtxt, TyVar}; +use rustc_middle::ty::{self, DelayedSet, Ty, TyCtxt, TyVar}; use rustc_span::Span; -use rustc_type_ir::data_structures::DelayedSet; use tracing::{debug, instrument}; use crate::infer::BoundRegionConversionTime::HigherRankedType; diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 245f1a4ac5ed..4b0ace8c554d 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,9 +1,8 @@ use rustc_middle::bug; use rustc_middle::ty::{ - self, Const, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder, + self, Const, DelayedMap, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; -use rustc_type_ir::data_structures::DelayedMap; use super::{FixupError, FixupResult, InferCtxt}; diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 39c8c40ea7d8..e210479581ba 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -3,9 +3,8 @@ use std::ops::Range; use rustc_data_structures::{snapshot_vec as sv, unify as ut}; use rustc_middle::ty::{ self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, - TypeSuperFoldable, + TypeSuperFoldable, TypeVisitableExt, }; -use rustc_type_ir::TypeVisitableExt; use tracing::instrument; use ut::UnifyKey; diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 66ed49fe3267..6461fbe0d33b 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; +pub use rustc_middle::ty::elaborate::*; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{Ident, Span}; -pub use rustc_type_ir::elaborate::*; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2f4c03f0953d..053845e3d69d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -50,9 +50,17 @@ use rustc_session::lint::LintBuffer; pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; -pub use rustc_type_ir::data_structures::DelayedSet; +pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet}; +#[allow( + hidden_glob_reexports, + rustc::usage_of_type_ir_inherent, + rustc::non_glob_import_of_type_ir_inherent +)] +use rustc_type_ir::inherent; pub use rustc_type_ir::relate::VarianceDiagInfo; pub use rustc_type_ir::*; +#[allow(hidden_glob_reexports, unused_imports)] +use rustc_type_ir::{InferCtxtLike, Interner}; use tracing::{debug, instrument}; pub use vtable::*; use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir}; diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index a5cc8d9ea012..1c61e23362a8 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -21,6 +21,7 @@ rustc_parse_format = { path = "../rustc_parse_format" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } +rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2" tracing = "0.1" diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index ef64da131891..908c058aabec 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -156,9 +156,9 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< fn register_hidden_type_in_storage( &self, opaque_type_key: ty::OpaqueTypeKey<'tcx>, - hidden_ty: ::Ty, - span: ::Span, - ) -> Option<::Ty> { + hidden_ty: ::Ty, + span: ::Span, + ) -> Option<::Ty> { self.0.register_hidden_type_in_storage( opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }, From 6f1a54bad27c49071efc11bcdb57f1bf152f7cb9 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 2 May 2025 11:16:56 +0200 Subject: [PATCH 068/262] Remove fragile equal-pointers-unequal tests. These randomly break when i change the implementation of format_args!(). --- .../equal-pointers-unequal/as-cast/basic.rs | 21 ---------------- .../as-cast/function.rs | 22 ----------------- .../equal-pointers-unequal/as-cast/print.rs | 20 ---------------- .../exposed-provenance/basic.rs | 23 ------------------ .../exposed-provenance/function.rs | 24 ------------------- .../exposed-provenance/print.rs | 22 ----------------- .../strict-provenance/basic.rs | 23 ------------------ .../strict-provenance/function.rs | 24 ------------------- .../strict-provenance/print.rs | 22 ----------------- 9 files changed, 201 deletions(-) delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs delete mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs deleted file mode 100644 index e2a00ce173d1..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -fn main() { - let a: usize = { - let v = 0u8; - &v as *const _ as usize - }; - let b: usize = { - let v = 0u8; - &v as *const _ as usize - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs deleted file mode 100644 index 15434de50f76..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -fn f() -> usize { - let v = 0; - &v as *const _ as usize -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs deleted file mode 100644 index f33a9e511b61..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -fn main() { - let a = { - let v = 0; - &v as *const _ as usize - }; - let b = { - let v = 0; - &v as *const _ as usize - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs deleted file mode 100644 index b2b4934aa5f1..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0u8; - ptr::from_ref(&v).expose_provenance() - }; - let b: usize = { - let v = 0u8; - ptr::from_ref(&v).expose_provenance() - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs deleted file mode 100644 index bf130c9f7598..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -use std::ptr; - -fn f() -> usize { - let v = 0; - ptr::from_ref(&v).expose_provenance() -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs deleted file mode 100644 index 0baf8886395e..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0; - ptr::from_ref(&v).expose_provenance() - }; - let b: usize = { - let v = 0; - ptr::from_ref(&v).expose_provenance() - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs deleted file mode 100644 index 4602ec654d10..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0u8; - ptr::from_ref(&v).addr() - }; - let b: usize = { - let v = 0u8; - ptr::from_ref(&v).addr() - }; - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs deleted file mode 100644 index 789a78c15b4e..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 - -use std::ptr; - -fn f() -> usize { - let v = 0; - ptr::from_ref(&v).addr() -} - -fn main() { - let a = f(); - let b = f(); - - // `a` and `b` are not equal. - assert_ne!(a, b); - // But they are the same number. - assert_eq!(format!("{a}"), format!("{b}")); - // And they are equal. - assert_eq!(a, b); -} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs deleted file mode 100644 index b7165ce1e5ce..000000000000 --- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #107975 -//@ compile-flags: -Copt-level=2 -//@ run-pass - -// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 - -use std::ptr; - -fn main() { - let a: usize = { - let v = 0; - ptr::from_ref(&v).addr() - }; - let b: usize = { - let v = 0; - ptr::from_ref(&v).addr() - }; - - assert_ne!(a, b); - println!("{a}"); // or b - assert_eq!(a, b); -} From ddff38703a3e56b26f5a73d56208a8adab5daae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 2 May 2025 12:24:47 +0200 Subject: [PATCH 069/262] Rename parameter to `override_def_path_data` --- compiler/rustc_middle/src/ty/context.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fffbf0513482..66ba39761ee1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1957,10 +1957,11 @@ impl<'tcx> TyCtxtAt<'tcx> { parent: LocalDefId, name: Option, def_kind: DefKind, - def_path_data: Option, + override_def_path_data: Option, disambiguator: &mut DisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { - let feed = self.tcx.create_def(parent, name, def_kind, def_path_data, disambiguator); + let feed = + self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator); feed.def_span(self.span); feed @@ -1974,10 +1975,10 @@ impl<'tcx> TyCtxt<'tcx> { parent: LocalDefId, name: Option, def_kind: DefKind, - def_path_data: Option, + override_def_path_data: Option, disambiguator: &mut DisambiguatorState, ) -> TyCtxtFeed<'tcx, LocalDefId> { - let data = def_path_data.unwrap_or_else(|| def_kind.def_path_data(name)); + let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name)); // The following call has the side effect of modifying the tables inside `definitions`. // These very tables are relied on by the incr. comp. engine to decode DepNodes and to // decode the on-disk cache. From abc57dcc0b4c1254f08404b0c45b48c56df365b1 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 May 2025 18:36:04 +0800 Subject: [PATCH 070/262] Remove estebank from automated review assignment --- triagebot.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 422996cb200d..e42d15e1b94d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1161,7 +1161,6 @@ compiler = [ "@BoxyUwU", "@compiler-errors", "@davidtwco", - "@estebank", "@fee1-dead", "@fmease", "@jieyouxu", @@ -1221,14 +1220,12 @@ incremental = [ diagnostics = [ "@compiler-errors", "@davidtwco", - "@estebank", "@oli-obk", "@chenyukang", ] parser = [ "@compiler-errors", "@davidtwco", - "@estebank", "@nnethercote", "@petrochenkov", "@spastorino", @@ -1236,7 +1233,6 @@ parser = [ lexer = [ "@nnethercote", "@petrochenkov", - "@estebank", "@chenyukang", ] arena = [ @@ -1268,7 +1264,6 @@ borrowck = [ ] ast_lowering = [ "@compiler-errors", - "@estebank", "@spastorino", ] debuginfo = [ From 2f2d3c887063d41cf361f58b34c0e0b48c83398f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Apr 2025 15:17:33 +0200 Subject: [PATCH 071/262] forbidden target feature tests: consolidate multiple tests in a single one with revisions --- ...dfloat-target-feature-flag-disable-implied.rs | 15 --------------- ...hardfloat-target-feature-flag-disable-neon.rs | 13 ------------- ...t-target-feature-flag-disable.aarch64.stderr} | 0 ...dden-hardfloat-target-feature-flag-disable.rs | 16 +++++++++++----- ...rget-feature-flag-disable.x86-implied.stderr} | 0 ...float-target-feature-flag-disable.x86.stderr} | 0 6 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs delete mode 100644 tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable-neon.stderr => forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable-implied.stderr => forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable.stderr => forbidden-hardfloat-target-feature-flag-disable.x86.stderr} (100%) diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs deleted file mode 100644 index 12e7e3bc45b3..000000000000 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Ensure that if disabling a target feature implies disabling an ABI-required target feature, -//! we complain. -//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib -//@ needs-llvm-components: x86 -//@ compile-flags: -Ctarget-feature=-sse -// For now this is just a warning. -//@ build-pass - -#![feature(no_core, lang_items)] -#![no_core] - -#[lang = "sized"] -pub trait Sized {} - -//~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs deleted file mode 100644 index 33e4f12694f3..000000000000 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=lib -//@ needs-llvm-components: aarch64 -//@ compile-flags: -Ctarget-feature=-neon -// For now this is just a warning. -//@ build-pass - -#![feature(no_core, lang_items)] -#![no_core] - -#[lang = "sized"] -pub trait Sized {} - -//~? WARN target feature `neon` must be enabled to ensure that the ABI of the current target can be implemented correctly diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr rename to tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs index e1bd25ffad1e..e0d095844fbb 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs @@ -1,7 +1,13 @@ //! Ensure ABI-required features cannot be disabled via `-Ctarget-feature`. -//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib -//@ needs-llvm-components: x86 -//@ compile-flags: -Ctarget-feature=-x87 +//! Also covers the case of a feature indirectly disabling another via feature implications. +//@ compile-flags: --crate-type=lib +//@ revisions: x86 x86-implied aarch64 +//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-x87 +//@[x86] needs-llvm-components: x86 +//@[x86-implied] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-sse +//@[x86-implied] needs-llvm-components: x86 +//@[aarch64] compile-flags: --target=aarch64-unknown-linux-gnu -Ctarget-feature=-neon +//@[aarch64] needs-llvm-components: aarch64 // For now this is just a warning. //@ build-pass @@ -11,5 +17,5 @@ #[lang = "sized"] pub trait Sized {} -//~? WARN target feature `x87` must be enabled to ensure that the ABI of the current target can be implemented correctly -//~? WARN unstable feature specified for `-Ctarget-feature`: `x87` +//~? WARN must be enabled to ensure that the ABI of the current target can be implemented correctly +//[x86]~? WARN unstable feature specified for `-Ctarget-feature` diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.stderr rename to tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr rename to tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86.stderr From 7a2d51dc29c0184bc97a373231634e07d6f1f0f9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Apr 2025 15:22:14 +0200 Subject: [PATCH 072/262] give the abi-relevant target feature tests better names --- ...tribute.rs => abi-incompatible-target-feature-attribute.rs} | 0 ...stderr => abi-incompatible-target-feature-attribute.stderr} | 2 +- ...-flag.rs => abi-incompatible-target-feature-flag-enable.rs} | 0 ...derr => abi-incompatible-target-feature-flag-enable.stderr} | 0 ...isable.rs => abi-irrelevant-target-feature-flag-disable.rs} | 3 +++ ...tderr => abi-irrelevant-target-feature-flag-disable.stderr} | 0 ...e-attribute.rs => abi-required-target-feature-attribute.rs} | 2 ++ ...=> abi-required-target-feature-flag-disable.aarch64.stderr} | 0 ...-disable.rs => abi-required-target-feature-flag-disable.rs} | 0 ...bi-required-target-feature-flag-disable.x86-implied.stderr} | 0 ...err => abi-required-target-feature-flag-disable.x86.stderr} | 0 11 files changed, 6 insertions(+), 1 deletion(-) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-attribute.rs => abi-incompatible-target-feature-attribute.rs} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-attribute.stderr => abi-incompatible-target-feature-attribute.stderr} (78%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag.rs => abi-incompatible-target-feature-flag-enable.rs} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag.stderr => abi-incompatible-target-feature-flag-enable.stderr} (100%) rename tests/ui/target-feature/{allowed-softfloat-target-feature-flag-disable.rs => abi-irrelevant-target-feature-flag-disable.rs} (59%) rename tests/ui/target-feature/{allowed-softfloat-target-feature-flag-disable.stderr => abi-irrelevant-target-feature-flag-disable.stderr} (100%) rename tests/ui/target-feature/{allowed-softfloat-target-feature-attribute.rs => abi-required-target-feature-attribute.rs} (69%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr => abi-required-target-feature-flag-disable.aarch64.stderr} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable.rs => abi-required-target-feature-flag-disable.rs} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr => abi-required-target-feature-flag-disable.x86-implied.stderr} (100%) rename tests/ui/target-feature/{forbidden-hardfloat-target-feature-flag-disable.x86.stderr => abi-required-target-feature-flag-disable.x86.stderr} (100%) diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs rename to tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr similarity index 78% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr rename to tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr index bfe767e5ffb0..baa8551b17a3 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:10:18 + --> $DIR/abi-incompatible-target-feature-attribute.rs:10:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs rename to tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr rename to tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.stderr diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs similarity index 59% rename from tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs rename to tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs index 7368ef120fa6..0013d033b9c5 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs @@ -1,3 +1,6 @@ +//! `x87` is a required target feature on some x86 targets, but not on this one as this one +//! uses soft-floats. So ensure disabling the target feature here (which is a NOP) does +//! not trigger a warning. //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib //@ needs-llvm-components: x86 //@ compile-flags: -Ctarget-feature=-x87 diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.stderr similarity index 100% rename from tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr rename to tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.stderr diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/abi-required-target-feature-attribute.rs similarity index 69% rename from tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs rename to tests/ui/target-feature/abi-required-target-feature-attribute.rs index 8b60820cc9b6..95723c57f94d 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-required-target-feature-attribute.rs @@ -1,3 +1,5 @@ +//! Enabling a target feature that is anyway required changes nothing, so this is allowed +//! for `#[target_feature]`. //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib //@ needs-llvm-components: x86 //@ build-pass diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.aarch64.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.aarch64.stderr rename to tests/ui/target-feature/abi-required-target-feature-flag-disable.aarch64.stderr diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs rename to tests/ui/target-feature/abi-required-target-feature-flag-disable.rs diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86-implied.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86-implied.stderr rename to tests/ui/target-feature/abi-required-target-feature-flag-disable.x86-implied.stderr diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr similarity index 100% rename from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.x86.stderr rename to tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr From efc51ce993f27cfb192e37f936941ff613846b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 2 May 2025 13:17:47 +0200 Subject: [PATCH 073/262] Add `DefPathData::NestedStatic` instead of reusing `DefPathData::AnonConst` --- compiler/rustc_const_eval/src/interpret/intern.rs | 7 +++---- compiler/rustc_hir/src/def.rs | 3 --- compiler/rustc_hir/src/definitions.rs | 6 +++++- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 1 + 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index adf2c255d089..47cc2d49fe27 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -17,14 +17,13 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; -use rustc_hir::definitions::DisambiguatorState; +use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult}; use rustc_middle::query::TyCtxtAt; use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::def_id::LocalDefId; -use rustc_span::sym; use tracing::{instrument, trace}; use super::{ @@ -108,9 +107,9 @@ fn intern_as_new_static<'tcx>( ) { let feed = tcx.create_def( static_id, - Some(sym::nested), - DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, None, + DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, + Some(DefPathData::NestedStatic), disambiguator, ); tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 5872ec5aedf2..507c94aca8b9 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -273,9 +273,6 @@ impl DefKind { // but those provide their own DefPathData. DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()), - // It's not exactly an anon const, but wrt DefPathData, there - // is no difference. - DefKind::Static { nested: true, .. } => DefPathData::AnonConst, DefKind::Fn | DefKind::Const | DefKind::ConstParam diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d66775cd20b0..74ef2f5557c8 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -313,6 +313,8 @@ pub enum DefPathData { AnonAssocTy(Symbol), /// A synthetic body for a coroutine's by-move body. SyntheticCoroutineBody, + /// Additional static data referred to by a static. + NestedStatic, } impl Definitions { @@ -455,7 +457,8 @@ impl DefPathData { | Ctor | AnonConst | OpaqueTy - | SyntheticCoroutineBody => None, + | SyntheticCoroutineBody + | NestedStatic => None, } } @@ -477,6 +480,7 @@ impl DefPathData { OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque }, AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc }, SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic }, + NestedStatic => DefPathDataName::Anon { namespace: sym::nested }, } } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index ed32c34bb4b5..f7f354d12e8c 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -717,6 +717,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { hir::definitions::DefPathData::AnonConst => "k", hir::definitions::DefPathData::OpaqueTy => "i", hir::definitions::DefPathData::SyntheticCoroutineBody => "s", + hir::definitions::DefPathData::NestedStatic => "n", hir::definitions::DefPathData::CrateRoot | hir::definitions::DefPathData::Use | hir::definitions::DefPathData::GlobalAsm diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 12aa876045c4..22c3955fa73f 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -851,6 +851,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { DefPathData::AnonConst => 'k', DefPathData::OpaqueTy => 'i', DefPathData::SyntheticCoroutineBody => 's', + DefPathData::NestedStatic => 'n', // These should never show up as `path_append` arguments. DefPathData::CrateRoot From d16daf5cbaed54758eaf928ee3f63528c2da6efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 2 May 2025 13:37:22 +0200 Subject: [PATCH 074/262] Add comment about the symbol on `AnonAssocTy` --- compiler/rustc_hir/src/definitions.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 74ef2f5557c8..1a0af38517a5 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -309,7 +309,8 @@ pub enum DefPathData { /// An existential `impl Trait` type node. /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name. OpaqueTy, - /// An anonymous associated type from an RPITIT. + /// An anonymous associated type from an RPITIT. The symbol refers to the name of the method + /// that defined the type. AnonAssocTy(Symbol), /// A synthetic body for a coroutine's by-move body. SyntheticCoroutineBody, From 4869e20e26c113165a3db23a3f7ad0ed2dc0463f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 2 May 2025 13:40:49 +0200 Subject: [PATCH 075/262] Split `get_opt_name` hashing use into `hashed_symbol` --- compiler/rustc_hir/src/definitions.rs | 22 +++++++++++++++++++- compiler/rustc_middle/src/ty/print/pretty.rs | 4 ---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 1a0af38517a5..98b41187f114 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -145,7 +145,7 @@ impl DefKey { let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data; std::mem::discriminant(data).hash(&mut hasher); - if let Some(name) = data.get_opt_name() { + if let Some(name) = data.hashed_symbol() { // Get a stable hash by considering the symbol chars rather than // the symbol index. name.as_str().hash(&mut hasher); @@ -443,6 +443,26 @@ pub enum DefPathDataName { impl DefPathData { pub fn get_opt_name(&self) -> Option { + use self::DefPathData::*; + match *self { + TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), + + Impl + | ForeignMod + | CrateRoot + | Use + | GlobalAsm + | Closure + | Ctor + | AnonConst + | OpaqueTy + | AnonAssocTy(..) + | SyntheticCoroutineBody + | NestedStatic => None, + } + } + + fn hashed_symbol(&self) -> Option { use self::DefPathData::*; match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f589c7df6285..1df3bff52442 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -391,10 +391,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let visible_parent_map = self.tcx().visible_parent_map(()); let kind = self.tcx().def_kind(def_id); - if let DefPathData::AnonAssocTy(..) = key.disambiguated_data.data { - return Ok(false); - } - let get_local_name = |this: &Self, name, def_id, key: DefKey| { if let Some(visible_parent) = visible_parent_map.get(&def_id) && let actual_parent = this.tcx().opt_parent(def_id) From 6873a46626fef5f8f95488272fc605b4847d011e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Apr 2025 15:40:44 +0200 Subject: [PATCH 076/262] add more revisions to cover more architectures --- ...ible-target-feature-attribute.riscv.stderr | 8 +++++++ ...i-incompatible-target-feature-attribute.rs | 13 ++++++++---- ...compatible-target-feature-attribute.stderr | 8 ------- ...atible-target-feature-attribute.x86.stderr | 8 +++++++ ...le-target-feature-flag-enable.riscv.stderr | 19 +++++++++++++++++ ...incompatible-target-feature-flag-enable.rs | 21 ++++++++++++------- ...ble-target-feature-flag-enable.x86.stderr} | 0 ...rget-feature-flag-disable.loongarch.stderr | 11 ++++++++++ ...d-target-feature-flag-disable.riscv.stderr | 11 ++++++++++ ...bi-required-target-feature-flag-disable.rs | 10 +++++++-- 10 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr delete mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr create mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr create mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr rename tests/ui/target-feature/{abi-incompatible-target-feature-flag-enable.stderr => abi-incompatible-target-feature-flag-enable.x86.stderr} (100%) create mode 100644 tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr create mode 100644 tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr new file mode 100644 index 000000000000..49c5479275f3 --- /dev/null +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr @@ -0,0 +1,8 @@ +error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI + --> $DIR/abi-incompatible-target-feature-attribute.rs:15:90 + | +LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs index 215e64979f73..a87334407592 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs @@ -1,12 +1,17 @@ //! Ensure ABI-incompatible features cannot be enabled via `#[target_feature]`. -//@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib -//@ needs-llvm-components: riscv -#![feature(no_core, lang_items, riscv_target_feature)] +// ignore-tidy-linelength +//@ compile-flags: --crate-type=lib +//@ revisions: x86 riscv +//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu +//@[x86] needs-llvm-components: x86 +//@[riscv] compile-flags: --target=riscv32e-unknown-none-elf +//@[riscv] needs-llvm-components: riscv +#![feature(no_core, lang_items, riscv_target_feature, x87_target_feature)] #![no_core] #[lang = "sized"] pub trait Sized {} -#[target_feature(enable = "d")] +#[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] //~^ERROR: cannot be enabled with pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr deleted file mode 100644 index baa8551b17a3..000000000000 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/abi-incompatible-target-feature-attribute.rs:10:18 - | -LL | #[target_feature(enable = "d")] - | ^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr new file mode 100644 index 000000000000..81471fd7e303 --- /dev/null +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr @@ -0,0 +1,8 @@ +error: target feature `soft-float` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI + --> $DIR/abi-incompatible-target-feature-attribute.rs:15:32 + | +LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr new file mode 100644 index 000000000000..2dca0c220332 --- /dev/null +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr @@ -0,0 +1,19 @@ +warning: target feature `d` must be disabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: unstable feature specified for `-Ctarget-feature`: `d` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: unstable feature specified for `-Ctarget-feature`: `f` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: unstable feature specified for `-Ctarget-feature`: `zicsr` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: 4 warnings emitted + diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index 4ccc6e0e941f..68e1d3b9ddc6 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -1,15 +1,22 @@ //! Ensure ABI-incompatible features cannot be enabled via `-Ctarget-feature`. -//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib -//@ needs-llvm-components: x86 -//@ compile-flags: -Ctarget-feature=+soft-float -// For now this is just a warning. -//@ build-pass +// These are just warnings for now. +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: x86 riscv +//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=+soft-float +//@[x86] needs-llvm-components: x86 +//@[riscv] compile-flags: --target=riscv32e-unknown-none-elf -Ctarget-feature=+d +//@[riscv] needs-llvm-components: riscv #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] #[lang = "sized"] pub trait Sized {} +#[lang = "freeze"] +pub trait Freeze {} -//~? WARN target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctl -//~? WARN unstable feature specified for `-Ctarget-feature`: `soft-float` +//~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly +//~? WARN unstable feature specified for `-Ctarget-feature` +//[riscv]~? WARN unstable feature specified for `-Ctarget-feature` +//[riscv]~? WARN unstable feature specified for `-Ctarget-feature` diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr similarity index 100% rename from tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.stderr rename to tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr new file mode 100644 index 000000000000..35102e0571f4 --- /dev/null +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr @@ -0,0 +1,11 @@ +warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: unstable feature specified for `-Ctarget-feature`: `d` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: 2 warnings emitted + diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr new file mode 100644 index 000000000000..35102e0571f4 --- /dev/null +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr @@ -0,0 +1,11 @@ +warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: unstable feature specified for `-Ctarget-feature`: `d` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: 2 warnings emitted + diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs index e0d095844fbb..c3ce05baa64b 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs @@ -1,15 +1,21 @@ //! Ensure ABI-required features cannot be disabled via `-Ctarget-feature`. //! Also covers the case of a feature indirectly disabling another via feature implications. //@ compile-flags: --crate-type=lib -//@ revisions: x86 x86-implied aarch64 +//@ revisions: x86 x86-implied aarch64 riscv loongarch //@[x86] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-x87 //@[x86] needs-llvm-components: x86 //@[x86-implied] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-sse //@[x86-implied] needs-llvm-components: x86 //@[aarch64] compile-flags: --target=aarch64-unknown-linux-gnu -Ctarget-feature=-neon //@[aarch64] needs-llvm-components: aarch64 +//@[riscv] compile-flags: --target=riscv64gc-unknown-none-elf -Ctarget-feature=-d +//@[riscv] needs-llvm-components: riscv +//@[loongarch] compile-flags: --target=loongarch64-unknown-none -Ctarget-feature=-d +//@[loongarch] needs-llvm-components: loongarch // For now this is just a warning. //@ build-pass +// Remove some LLVM warnings that only show up sometimes. +//@ normalize-stderr: "\n[^\n]*(target-abi|lp64f)[^\n]*" -> "" #![feature(no_core, lang_items)] #![no_core] @@ -18,4 +24,4 @@ pub trait Sized {} //~? WARN must be enabled to ensure that the ABI of the current target can be implemented correctly -//[x86]~? WARN unstable feature specified for `-Ctarget-feature` +//[x86,riscv,loongarch]~? WARN unstable feature specified for `-Ctarget-feature` From ce4d3958501eaa0dd6bc00b57d2c569f06225957 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 May 2025 14:25:27 +0200 Subject: [PATCH 077/262] Update sysinfo version to `0.35.0` --- src/bootstrap/Cargo.lock | 145 +++++++++++++++++++++++++++++++++++---- src/bootstrap/Cargo.toml | 2 +- 2 files changed, 131 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index d415668f54a7..cdad3bd46fab 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -64,7 +64,7 @@ dependencies = [ "tracing-subscriber", "tracing-tree", "walkdir", - "windows", + "windows 0.57.0", "xz2", ] @@ -158,12 +158,6 @@ dependencies = [ "cc", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - [[package]] name = "cpufeatures" version = "0.2.15" @@ -440,6 +434,25 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +dependencies = [ + "libc", + "objc2-core-foundation", +] + [[package]] name = "object" version = "0.36.5" @@ -700,15 +713,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "948512566b1895f93b1592c7574baeb2de842f224f2aab158799ecadb8ebbb46" +checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422" dependencies = [ - "core-foundation-sys", "libc", "memchr", "ntapi", - "windows", + "objc2-core-foundation", + "objc2-io-kit", + "windows 0.61.1", ] [[package]] @@ -927,22 +941,67 @@ version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core", + "windows-core 0.57.0", "windows-targets", ] +[[package]] +name = "windows" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +dependencies = [ + "windows-collections", + "windows-core 0.61.0", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.0", +] + [[package]] name = "windows-core" version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", "windows-targets", ] +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.2", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +dependencies = [ + "windows-core 0.61.0", + "windows-link", +] + [[package]] name = "windows-implement" version = "0.57.0" @@ -954,6 +1013,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.57.0" @@ -965,6 +1035,33 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.0", + "windows-link", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -974,6 +1071,24 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 712a9b04c1a1..e34de924cc18 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -58,7 +58,7 @@ walkdir = "2.4" xz2 = "0.1" # Dependencies needed by the build-metrics feature -sysinfo = { version = "0.33.0", default-features = false, optional = true, features = ["system"] } +sysinfo = { version = "0.35.0", default-features = false, optional = true, features = ["system"] } # Dependencies needed by the `tracing` feature tracing = { version = "0.1", optional = true, features = ["attributes"] } From fbfc3297955faa53d62b480f91a0a7d10918bbf3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 May 2025 14:27:27 +0200 Subject: [PATCH 078/262] Update sysinfo to `0.35.0` in `src/tools/opt-dist` --- Cargo.lock | 101 ++++++++++++---------------------- src/tools/opt-dist/Cargo.toml | 2 +- 2 files changed, 35 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 361d237b3af8..5ea2f885cca4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,7 +747,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows 0.59.0", + "windows", ] [[package]] @@ -2466,6 +2466,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +dependencies = [ + "libc", + "objc2-core-foundation", +] + [[package]] name = "object" version = "0.32.2" @@ -3469,7 +3488,7 @@ dependencies = [ "thorin-dwp", "tracing", "wasm-encoder 0.219.2", - "windows 0.59.0", + "windows", ] [[package]] @@ -3528,7 +3547,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows 0.59.0", + "windows", ] [[package]] @@ -3591,7 +3610,7 @@ dependencies = [ "serde_json", "shlex", "tracing", - "windows 0.59.0", + "windows", ] [[package]] @@ -3646,7 +3665,7 @@ dependencies = [ "termcolor", "termize", "tracing", - "windows 0.59.0", + "windows", ] [[package]] @@ -4389,7 +4408,7 @@ dependencies = [ "smallvec", "termize", "tracing", - "windows 0.59.0", + "windows", ] [[package]] @@ -5071,13 +5090,14 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.31.4" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422" dependencies = [ - "core-foundation-sys", "libc", - "windows 0.57.0", + "objc2-core-foundation", + "objc2-io-kit", + "windows", ] [[package]] @@ -5952,16 +5972,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.59.0" @@ -5983,18 +5993,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.59.0" @@ -6002,8 +6000,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce" dependencies = [ "windows-implement 0.59.0", - "windows-interface 0.59.1", - "windows-result 0.3.2", + "windows-interface", + "windows-result", "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -6015,23 +6013,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ "windows-implement 0.60.0", - "windows-interface 0.59.1", + "windows-interface", "windows-link", - "windows-result 0.3.2", + "windows-result", "windows-strings 0.4.0", ] -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "windows-implement" version = "0.59.0" @@ -6054,17 +6041,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "windows-interface" version = "0.59.1" @@ -6082,15 +6058,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-result" version = "0.3.2" diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index cea234cc74cb..b0db8346f7ed 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -10,7 +10,7 @@ log = "0.4" anyhow = "1" humantime = "2" humansize = "2" -sysinfo = { version = "0.31.2", default-features = false, features = ["disk"] } +sysinfo = { version = "0.35.0", default-features = false, features = ["disk"] } fs_extra = "1" camino = "1" tar = "0.4" From f20e853e65b7b957c5d829c506cef3ab88ad5a9a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 14 Apr 2025 10:17:22 +0200 Subject: [PATCH 079/262] Render more lifetimes --- .../crates/hir-ty/src/display.rs | 69 ++++++++++++++-- .../crates/hir-ty/src/tests/coercion.rs | 6 +- .../hir-ty/src/tests/display_source_code.rs | 18 ++--- .../hir-ty/src/tests/method_resolution.rs | 8 +- .../crates/hir-ty/src/tests/regression.rs | 4 +- .../crates/hir-ty/src/tests/simple.rs | 10 +-- .../crates/hir-ty/src/tests/traits.rs | 78 +++++++++---------- .../src/handlers/convert_closure_to_fn.rs | 6 +- .../src/handlers/extract_function.rs | 2 +- .../src/handlers/extract_variable.rs | 28 +++---- .../src/handlers/generate_function.rs | 8 +- .../crates/ide-assists/src/tests/generated.rs | 2 +- .../ide-completion/src/tests/expression.rs | 2 +- .../ide-completion/src/tests/special.rs | 4 +- .../ide-completion/src/tests/type_pos.rs | 18 ++--- .../src/handlers/expected_function.rs | 2 +- .../src/handlers/invalid_cast.rs | 6 +- .../src/handlers/type_mismatch.rs | 7 +- .../src/handlers/typed_hole.rs | 2 +- .../src/handlers/unresolved_method.rs | 2 +- .../crates/ide/src/hover/tests.rs | 42 +++++----- .../crates/ide/src/inlay_hints/bind_pat.rs | 20 ++--- .../ide/src/inlay_hints/closing_brace.rs | 2 +- .../rust-analyzer/tests/slow-tests/main.rs | 4 +- 24 files changed, 201 insertions(+), 149 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index e810467b994a..f0989d9de91f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -90,11 +90,26 @@ pub struct HirFormatter<'a> { show_container_bounds: bool, omit_verbose_types: bool, closure_style: ClosureStyle, + display_lifetimes: DisplayLifetime, display_kind: DisplayKind, display_target: DisplayTarget, bounds_formatting_ctx: BoundsFormattingCtx, } +// FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should +// not be when in signatures +// So this enum does not encode this well enough +// Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types +// FIXME: Also named lifetimes may be rendered in places where their name is not in scope? +#[derive(Copy, Clone)] +pub enum DisplayLifetime { + Always, + OnlyStatic, + OnlyNamed, + OnlyNamedOrStatic, + Never, +} + #[derive(Default)] enum BoundsFormattingCtx { Entered { @@ -155,6 +170,21 @@ impl HirFormatter<'_> { } } } + + fn render_lifetime(&self, lifetime: &Lifetime) -> bool { + match self.display_lifetimes { + DisplayLifetime::Always => true, + DisplayLifetime::OnlyStatic => matches!(***lifetime.interned(), LifetimeData::Static), + DisplayLifetime::OnlyNamed => { + matches!(***lifetime.interned(), LifetimeData::Placeholder(_)) + } + DisplayLifetime::OnlyNamedOrStatic => matches!( + ***lifetime.interned(), + LifetimeData::Static | LifetimeData::Placeholder(_) + ), + DisplayLifetime::Never => false, + } + } } pub trait HirDisplay { @@ -189,6 +219,7 @@ pub trait HirDisplay { display_kind, closure_style, show_container_bounds, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, } } @@ -212,6 +243,7 @@ pub trait HirDisplay { display_target, display_kind: DisplayKind::Diagnostics, show_container_bounds: false, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, } } @@ -236,6 +268,7 @@ pub trait HirDisplay { display_target, display_kind: DisplayKind::Diagnostics, show_container_bounds: false, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, } } @@ -260,6 +293,7 @@ pub trait HirDisplay { display_target, display_kind: DisplayKind::Diagnostics, show_container_bounds: false, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, } } @@ -284,6 +318,7 @@ pub trait HirDisplay { display_target: DisplayTarget::from_crate(db, module_id.krate()), display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque }, show_container_bounds: false, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, bounds_formatting_ctx: Default::default(), }) { Ok(()) => {} @@ -312,6 +347,7 @@ pub trait HirDisplay { display_target, display_kind: DisplayKind::Test, show_container_bounds: false, + display_lifetimes: DisplayLifetime::Always, } } @@ -336,6 +372,7 @@ pub trait HirDisplay { display_target, display_kind: DisplayKind::Diagnostics, show_container_bounds, + display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, } } } @@ -480,6 +517,7 @@ pub struct HirDisplayWrapper<'a, T> { display_kind: DisplayKind, display_target: DisplayTarget, show_container_bounds: bool, + display_lifetimes: DisplayLifetime, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -502,7 +540,7 @@ impl HirDisplayWrapper<'_, T> { self.t.hir_fmt(&mut HirFormatter { db: self.db, fmt: f, - buf: String::with_capacity(20), + buf: String::with_capacity(self.max_size.unwrap_or(20)), curr_size: 0, max_size: self.max_size, entity_limit: self.limited_size, @@ -511,6 +549,7 @@ impl HirDisplayWrapper<'_, T> { display_target: self.display_target, closure_style: self.closure_style, show_container_bounds: self.show_container_bounds, + display_lifetimes: self.display_lifetimes, bounds_formatting_ctx: Default::default(), }) } @@ -519,6 +558,11 @@ impl HirDisplayWrapper<'_, T> { self.closure_style = c; self } + + pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self { + self.display_lifetimes = l; + self + } } impl fmt::Display for HirDisplayWrapper<'_, T> @@ -1022,9 +1066,7 @@ impl HirDisplay for Ty { kind @ (TyKind::Raw(m, t) | TyKind::Ref(m, _, t)) => { if let TyKind::Ref(_, l, _) = kind { f.write_char('&')?; - if cfg!(test) { - // rendering these unconditionally is probably too much (at least for inlay - // hints) so we gate it to testing only for the time being + if f.render_lifetime(l) { l.hir_fmt(f)?; f.write_char(' ')?; } @@ -1055,9 +1097,10 @@ impl HirDisplay for Ty { }) }; let (preds_to_print, has_impl_fn_pred) = match t.kind(Interner) { - TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { + TyKind::Dyn(dyn_ty) => { let bounds = dyn_ty.bounds.skip_binders().interned(); - (bounds.len(), contains_impl_fn(bounds)) + let render_lifetime = f.render_lifetime(&dyn_ty.lifetime); + (bounds.len() + render_lifetime as usize, contains_impl_fn(bounds)) } TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, @@ -1479,7 +1522,7 @@ impl HirDisplay for Ty { TyKind::BoundVar(idx) => idx.hir_fmt(f)?, TyKind::Dyn(dyn_ty) => { // Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation. - // FIXME: `Iterator::partition_in_place()` or `Vec::drain_filter()` may make it + // FIXME: `Iterator::partition_in_place()` or `Vec::extract_if()` may make it // more efficient when either of them hits stable. let mut bounds: SmallVec<[_; 4]> = dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect(); @@ -1488,6 +1531,17 @@ impl HirDisplay for Ty { bounds.extend(others); bounds.extend(auto_traits); + if f.render_lifetime(&dyn_ty.lifetime) { + // we skip the binders in `write_bounds_like_dyn_trait_with_prefix` + bounds.push(Binders::empty( + Interner, + chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives { + ty: self.clone(), + lifetime: dyn_ty.lifetime.clone(), + }), + )); + } + write_bounds_like_dyn_trait_with_prefix( f, "dyn", @@ -1989,7 +2043,6 @@ impl HirDisplay for LifetimeData { write!(f, "{}", param_data.name.display(f.db, f.edition()))?; Ok(()) } - _ if f.display_kind.is_source_code() => write!(f, "'_"), LifetimeData::BoundVar(idx) => idx.hir_fmt(f), LifetimeData::InferenceVar(_) => write!(f, "_"), LifetimeData::Static => write!(f, "'static"), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs index eeaacbf12eac..ddc5b715194d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs @@ -561,7 +561,7 @@ trait Foo {} fn test(f: impl Foo, g: &(impl Foo + ?Sized)) { let _: &dyn Foo = &f; let _: &dyn Foo = g; - //^ expected &'? dyn Foo, got &'? impl Foo + ?Sized + //^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized } "#, ); @@ -827,11 +827,11 @@ struct V { t: T } fn main() { let a: V<&dyn Tr>; (a,) = V { t: &S }; - //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,) + //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,) let mut a: V<&dyn Tr> = V { t: &S }; (a,) = V { t: &S }; - //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,) + //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,) } "#, ); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs index 60c03b52246c..a986b54a7b06 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs @@ -65,13 +65,13 @@ trait A { } trait B: A {} -fn test( +fn test<'a>( _: &(dyn A + Send), - //^ &'_ (dyn A + Send) - _: &(dyn Send + A), - //^ &'_ (dyn A + Send) + //^ &(dyn A + Send + 'static) + _: &'a (dyn Send + A), + //^ &'a (dyn A + Send + 'static) _: &dyn B, - //^ &'_ (dyn B) + //^ &(dyn B + 'static) ) {} "#, ); @@ -85,7 +85,7 @@ fn render_dyn_for_ty() { trait Foo<'a> {} fn foo(foo: &dyn for<'a> Foo<'a>) {} - // ^^^ &'_ dyn Foo<'_> + // ^^^ &(dyn Foo<'?> + 'static) "#, ); } @@ -111,11 +111,11 @@ fn test( b; //^ impl Foo c; - //^ &'_ impl Foo + ?Sized + //^ &impl Foo + ?Sized d; //^ S ref_any; - //^^^^^^^ &'_ impl ?Sized + //^^^^^^^ &impl ?Sized empty; } //^^^^^ impl Sized "#, @@ -192,7 +192,7 @@ fn test( b; //^ fn(impl Foo) -> impl Foo c; -} //^ fn(&'_ impl Foo + ?Sized) -> &'_ impl Foo + ?Sized +} //^ fn(&impl Foo + ?Sized) -> &impl Foo + ?Sized "#, ); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs index 3a258ecad10a..1f8b06fcc561 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs @@ -1153,9 +1153,9 @@ fn dyn_trait_super_trait_not_in_scope() { 51..55 'self': &'? Self 64..69 '{ 0 }': u32 66..67 '0': u32 - 176..177 'd': &'? dyn Trait + 176..177 'd': &'? (dyn Trait + 'static) 191..207 '{ ...o(); }': () - 197..198 'd': &'? dyn Trait + 197..198 'd': &'? (dyn Trait + 'static) 197..204 'd.foo()': u32 "#]], ); @@ -2019,10 +2019,10 @@ impl dyn Error + Send { /// Attempts to downcast the box to a concrete type. pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; - // ^^^^ expected Box, got Box + // ^^^^ expected Box, got Box // FIXME, type mismatch should not occur ::downcast(err).map_err(|_| loop {}) - //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box) -> Result, Box> + //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box) -> Result, Box> } } "#, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 638306054a9d..644b0d392bcf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -629,7 +629,7 @@ fn issue_4053_diesel_where_clauses() { 488..522 '{ ... }': () 498..502 'self': SelectStatement 498..508 'self.order': O - 498..515 'self.o...into()': dyn QueryFragment + 498..515 'self.o...into()': dyn QueryFragment + 'static "#]], ); } @@ -773,7 +773,7 @@ fn issue_4800() { "#, expect![[r#" 379..383 'self': &'? mut PeerSet - 401..424 '{ ... }': dyn Future + 401..424 '{ ... }': dyn Future + 'static 411..418 'loop {}': ! 416..418 '{}': () 575..579 'self': &'? mut Self diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 0f5e44151de2..eeebe38f1826 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -2741,11 +2741,11 @@ impl B for Astruct {} 715..744 '#[rust...1i32])': Box<[i32; 1], Global> 737..743 '[1i32]': [i32; 1] 738..742 '1i32': i32 - 755..756 'v': Vec, Global> - 776..793 '<[_]> ...to_vec': fn into_vec, Global>(Box<[Box], Global>) -> Vec, Global> - 776..850 '<[_]> ...ct)]))': Vec, Global> - 794..849 '#[rust...uct)])': Box<[Box; 1], Global> - 816..848 '[#[rus...ruct)]': [Box; 1] + 755..756 'v': Vec, Global> + 776..793 '<[_]> ...to_vec': fn into_vec, Global>(Box<[Box], Global>) -> Vec, Global> + 776..850 '<[_]> ...ct)]))': Vec, Global> + 794..849 '#[rust...uct)])': Box<[Box; 1], Global> + 816..848 '[#[rus...ruct)]': [Box; 1] 817..847 '#[rust...truct)': Box 839..846 'Astruct': Astruct "#]], diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 2fb51acea873..14137605c9f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -1475,26 +1475,26 @@ fn test(x: Box>, y: &dyn Trait) { expect![[r#" 29..33 'self': &'? Self 54..58 'self': &'? Self - 198..200 '{}': Box> - 210..211 'x': Box> - 234..235 'y': &'? dyn Trait + 198..200 '{}': Box + 'static> + 210..211 'x': Box + 'static> + 234..235 'y': &'? (dyn Trait + 'static) 254..371 '{ ...2(); }': () - 260..261 'x': Box> - 267..268 'y': &'? dyn Trait - 278..279 'z': Box> - 282..285 'bar': fn bar() -> Box> - 282..287 'bar()': Box> - 293..294 'x': Box> + 260..261 'x': Box + 'static> + 267..268 'y': &'? (dyn Trait + 'static) + 278..279 'z': Box + 'static> + 282..285 'bar': fn bar() -> Box + 'static> + 282..287 'bar()': Box + 'static> + 293..294 'x': Box + 'static> 293..300 'x.foo()': u64 - 306..307 'y': &'? dyn Trait + 306..307 'y': &'? (dyn Trait + 'static) 306..313 'y.foo()': u64 - 319..320 'z': Box> + 319..320 'z': Box + 'static> 319..326 'z.foo()': u64 - 332..333 'x': Box> + 332..333 'x': Box + 'static> 332..340 'x.foo2()': i64 - 346..347 'y': &'? dyn Trait + 346..347 'y': &'? (dyn Trait + 'static) 346..354 'y.foo2()': i64 - 360..361 'z': Box> + 360..361 'z': Box + 'static> 360..368 'z.foo2()': i64 "#]], ); @@ -1523,14 +1523,14 @@ fn test(s: S) { expect![[r#" 32..36 'self': &'? Self 102..106 'self': &'? S - 128..139 '{ loop {} }': &'? dyn Trait + 128..139 '{ loop {} }': &'? (dyn Trait + 'static) 130..137 'loop {}': ! 135..137 '{}': () 175..179 'self': &'? Self 251..252 's': S 267..289 '{ ...z(); }': () 273..274 's': S - 273..280 's.bar()': &'? dyn Trait + 273..280 's.bar()': &'? (dyn Trait + 'static) 273..286 's.bar().baz()': (u32, i32) "#]], ); @@ -1556,20 +1556,20 @@ fn test(x: Trait, y: &Trait) -> u64 { }"#, expect![[r#" 26..30 'self': &'? Self - 60..62 '{}': dyn Trait - 72..73 'x': dyn Trait - 82..83 'y': &'? dyn Trait + 60..62 '{}': dyn Trait + 'static + 72..73 'x': dyn Trait + 'static + 82..83 'y': &'? (dyn Trait + 'static) 100..175 '{ ...o(); }': u64 - 106..107 'x': dyn Trait - 113..114 'y': &'? dyn Trait - 124..125 'z': dyn Trait - 128..131 'bar': fn bar() -> dyn Trait - 128..133 'bar()': dyn Trait - 139..140 'x': dyn Trait + 106..107 'x': dyn Trait + 'static + 113..114 'y': &'? (dyn Trait + 'static) + 124..125 'z': dyn Trait + 'static + 128..131 'bar': fn bar() -> dyn Trait + 'static + 128..133 'bar()': dyn Trait + 'static + 139..140 'x': dyn Trait + 'static 139..146 'x.foo()': u64 - 152..153 'y': &'? dyn Trait + 152..153 'y': &'? (dyn Trait + 'static) 152..159 'y.foo()': u64 - 165..166 'z': dyn Trait + 165..166 'z': dyn Trait + 'static 165..172 'z.foo()': u64 "#]], ); @@ -1589,10 +1589,10 @@ fn main() { expect![[r#" 31..35 'self': &'? S 37..39 '{}': () - 47..48 '_': &'? dyn Fn(S) + 47..48 '_': &'? (dyn Fn(S) + 'static) 58..60 '{}': () 71..105 '{ ...()); }': () - 77..78 'f': fn f(&'? dyn Fn(S)) + 77..78 'f': fn f(&'? (dyn Fn(S) + 'static)) 77..102 'f(&|nu...foo())': () 79..101 '&|numb....foo()': &'? impl Fn(S) 80..101 '|numbe....foo()': impl Fn(S) @@ -2927,13 +2927,13 @@ fn test(x: &dyn Foo) { foo(x); }"#, expect![[r#" - 21..22 'x': &'? dyn Foo + 21..22 'x': &'? (dyn Foo + 'static) 34..36 '{}': () - 46..47 'x': &'? dyn Foo + 46..47 'x': &'? (dyn Foo + 'static) 59..74 '{ foo(x); }': () - 65..68 'foo': fn foo(&'? dyn Foo) + 65..68 'foo': fn foo(&'? (dyn Foo + 'static)) 65..71 'foo(x)': () - 69..70 'x': &'? dyn Foo + 69..70 'x': &'? (dyn Foo + 'static) "#]], ); } @@ -3210,13 +3210,13 @@ fn foo() { 218..324 '{ ...&s); }': () 228..229 's': Option 232..236 'None': Option - 246..247 'f': Box)> - 281..310 'Box { ... {}) }': Box)> + 246..247 'f': Box) + 'static> + 281..310 'Box { ... {}) }': Box) + 'static> 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option) 300..307 '|ps| {}': impl FnOnce(&'? Option) 301..303 'ps': &'? Option 305..307 '{}': () - 316..317 'f': Box)> + 316..317 'f': Box) + 'static> 316..321 'f(&s)': () 318..320 '&s': &'? Option 319..320 's': Option @@ -4252,9 +4252,9 @@ fn f<'a>(v: &dyn Trait = &'a i32>) { "#, expect![[r#" 90..94 'self': &'? Self - 127..128 'v': &'? (dyn Trait = &'a i32>) + 127..128 'v': &'? (dyn Trait = &'a i32> + 'static) 164..195 '{ ...f(); }': () - 170..171 'v': &'? (dyn Trait = &'a i32>) + 170..171 'v': &'? (dyn Trait = &'a i32> + 'static) 170..184 'v.get::()': &'? i32 170..192 'v.get:...eref()': &'? i32 "#]], @@ -4735,7 +4735,7 @@ pub async fn foo_async<'a>() -> Box { fn foo() { foo_async(); - //^^^^^^^^^^^impl Future> + ?Sized + //^^^^^^^^^^^impl Future> + ?Sized } "#, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs index 1d3a2db3352b..43515de71e20 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs @@ -1066,7 +1066,7 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) { *a = 1.2; let c = *b; } @@ -1098,7 +1098,7 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) { let _: &mut bool = p2; *a = 1.2; let c = *b; @@ -1136,7 +1136,7 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) { let _: &mut bool = p2; *a = 1.2; let c = *b; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 046af71a9dc0..e977798c4fd0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -5033,7 +5033,7 @@ fn main() { fun_name(bar); } -fn $0fun_name(bar: &str) { +fn $0fun_name(bar: &'static str) { m!(bar); } "#, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 3971b60f2532..31e84e9adcf4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -631,7 +631,7 @@ fn main() { "#, r#" fn main() { - const $0HELLO: &str = "hello"; + const $0HELLO: &'static str = "hello"; } "#, "Extract into constant", @@ -726,7 +726,7 @@ fn main() { "#, r#" fn main() { - static $0HELLO: &str = "hello"; + static $0HELLO: &'static str = "hello"; } "#, "Extract into static", @@ -2528,13 +2528,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { let entry = Entry($0"Hello"$0); } "#, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { let $0hello = "Hello"; let entry = Entry(hello); @@ -2546,13 +2546,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { let entry = Entry($0"Hello"$0); } "#, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { const $0HELLO: &str = "Hello"; let entry = Entry(HELLO); @@ -2564,13 +2564,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { let entry = Entry($0"Hello"$0); } "#, r#" -struct Entry(&str); +struct Entry<'a>(&'a str); fn foo() { static $0HELLO: &str = "Hello"; let entry = Entry(HELLO); @@ -2587,13 +2587,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { let entry = Entry { message: $0"Hello"$0 }; } "#, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { let $0message = "Hello"; let entry = Entry { message }; @@ -2605,13 +2605,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { let entry = Entry { message: $0"Hello"$0 }; } "#, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { const $0HELLO: &str = "Hello"; let entry = Entry { message: HELLO }; @@ -2623,13 +2623,13 @@ fn foo() { check_assist_by_label( extract_variable, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { let entry = Entry { message: $0"Hello"$0 }; } "#, r#" -struct Entry { message: &str } +struct Entry<'a> { message: &'a str } fn foo() { static $0HELLO: &str = "Hello"; let entry = Entry { message: HELLO }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index aac145a72150..30084d23d1fb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -47,7 +47,7 @@ use crate::{ // bar("", baz()); // } // -// fn bar(arg: &str, baz: Baz) ${0:-> _} { +// fn bar(arg: &'static str, baz: Baz) ${0:-> _} { // todo!() // } // @@ -1518,7 +1518,7 @@ fn foo() { bar("bar") } -fn bar(arg: &str) { +fn bar(arg: &'static str) { ${0:todo!()} } "#, @@ -2135,7 +2135,7 @@ fn foo() { bar(baz(), baz(), "foo", "bar") } -fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) { +fn bar(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) { ${0:todo!()} } "#, @@ -3103,7 +3103,7 @@ pub struct Foo { field_2: String, } impl Foo { - fn new(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) -> Self { + fn new(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) -> Self { ${0:Self { field_1: todo!(), field_2: todo!() }} } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 54d060cc7909..01ab0be34b28 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -1737,7 +1737,7 @@ fn foo() { bar("", baz()); } -fn bar(arg: &str, baz: Baz) ${0:-> _} { +fn bar(arg: &'static str, baz: Baz) ${0:-> _} { todo!() } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index 27d6bc7b14f2..d5137949d42f 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs @@ -1517,7 +1517,7 @@ fn main() { en Enum Enum fn function() fn() fn main() fn() - lc variable &str + lc variable &'static str ma helper!(…) macro_rules! helper ma m!(…) macro_rules! m ma makro!(…) macro_rules! makro diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs index 15518e98370e..148203107c4c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs @@ -1358,7 +1358,7 @@ pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone, { 0u8 } fn main() { fo$0 } "#, CompletionItemKind::SymbolKind(ide_db::SymbolKind::Function), - expect!("fn(&mut T) -> u8"), + expect!("fn(&'x mut T) -> u8"), expect!("pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone,"), ); @@ -1391,7 +1391,7 @@ fn main() { } "#, CompletionItemKind::SymbolKind(SymbolKind::Method), - expect!("const fn(&'foo mut self, &Foo) -> !"), + expect!("const fn(&'foo mut self, &'foo Foo) -> !"), expect!("pub const fn baz<'foo>(&'foo mut self, x: &'foo Foo) -> !"), ); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs index c7e2d058257e..125e11e9e358 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs @@ -429,18 +429,18 @@ trait Tr { impl Tr<$0 "#, expect![[r#" - en Enum Enum - ma makro!(…) macro_rules! makro + en Enum Enum + ma makro!(…) macro_rules! makro md module - sp Self dyn Tr<{unknown}> - st Record Record - st S S - st Tuple Tuple - st Unit Unit + sp Self dyn Tr<{unknown}> + 'static + st Record Record + st S S + st Tuple Tuple + st Unit Unit tt Tr tt Trait - un Union Union - bt u32 u32 + un Union Union + bt u32 u32 kw crate:: kw self:: "#]], diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs index af25c2b2e332..a6da0fd9c5e3 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs @@ -31,7 +31,7 @@ fn foo() { x(); // ^^^ error: expected function, found i32 ""(); - // ^^^^ error: expected function, found &str + // ^^^^ error: expected function, found &'static str foo(); } "#, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index b56255b1fde4..d72b21099ce3 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -166,7 +166,7 @@ fn main() { let _ = ptr as bool; //^^^^^^^^^^^ error: cannot cast `*const ()` as `bool` let v = "hello" as bool; - //^^^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first + //^^^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first } "#, ); @@ -956,7 +956,7 @@ fn main() { fn main() { let pointer: usize = &1_i32 as *const i32 as usize; let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 }; - //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&i32` + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&'static i32` } "#, ); @@ -992,7 +992,7 @@ impl Deref for Foo { fn main() { let _ = "foo" as bool; - //^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first + //^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first let _ = Foo as bool; //^^^^^^^^^^^ error: non-primitive cast: `Foo` as `bool` diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 1db9b6d04944..500c5de791dc 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -306,10 +306,9 @@ fn str_ref_to_owned( acc: &mut Vec, ) -> Option<()> { let expected = d.expected.display(ctx.sema.db, ctx.display_target); - let actual = d.actual.display(ctx.sema.db, ctx.display_target); - // FIXME do this properly - if expected.to_string() != "String" || actual.to_string() != "&str" { + let is_applicable = d.actual.strip_reference().is_str() && expected.to_string() == "String"; + if !is_applicable { return None; } @@ -1176,7 +1175,7 @@ trait B {} fn test(a: &dyn A) -> &dyn B { a - //^ error: expected &dyn B, found &dyn A + //^ error: expected &(dyn B + 'static), found &(dyn A + 'static) } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 1e7f00c23313..a933f1b42611 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -151,7 +151,7 @@ fn main() { fn main() { let mut x = t(); x = _; - //^ 💡 error: invalid `_` expression, expected type `&str` + //^ 💡 error: invalid `_` expression, expected type `&'static str` x = ""; } fn t() -> T { loop {} } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 4422d8f8262f..7f07009dc561 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -269,7 +269,7 @@ impl A { } fn main() { let a = A {a: 0, b: ""}; - A::::foo(); + A::::foo(); } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index d469cd7c0cd5..7b7eef9d5793 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -7085,9 +7085,9 @@ fn foo() { } "#, expect![[r#" - ```rust - &str - ```"#]], + ```rust + &'static str + ```"#]], ); } @@ -8228,7 +8228,7 @@ format_args!("{aaaaa$0}"); *aaaaa* ```rust - let aaaaa: &str + let aaaaa: &'static str ``` "#]], ); @@ -8248,7 +8248,7 @@ format_args!("{$0aaaaa}"); *aaaaa* ```rust - let aaaaa: &str + let aaaaa: &'static str ``` "#]], ); @@ -8268,7 +8268,7 @@ format_args!(r"{$0aaaaa}"); *aaaaa* ```rust - let aaaaa: &str + let aaaaa: &'static str ``` "#]], ); @@ -8293,7 +8293,7 @@ foo!(r"{$0aaaaa}"); *aaaaa* ```rust - let aaaaa: &str + let aaaaa: &'static str ``` "#]], ); @@ -8337,7 +8337,7 @@ fn main() { expect![[r#" *"🦀\u{1f980}\\\x41"* ```rust - &str + &'static str ``` ___ @@ -8353,7 +8353,7 @@ fn main() { expect![[r#" *r"🦀\u{1f980}\\\x41"* ```rust - &str + &'static str ``` ___ @@ -8375,7 +8375,7 @@ fsdghs"; fsdghs"* ```rust - &str + &'static str ``` ___ @@ -8395,7 +8395,7 @@ fn main() { expect![[r#" *c"🦀\u{1f980}\\\x41"* ```rust - &{unknown} + &'static {unknown} ``` ___ @@ -8414,7 +8414,7 @@ fn main() { expect![[r#" *r"`[^`]*`"* ```rust - &str + &'static str ``` ___ @@ -8429,7 +8429,7 @@ fn main() { expect![[r#" *r"`"* ```rust - &str + &'static str ``` ___ @@ -8444,7 +8444,7 @@ fn main() { expect![[r#" *r" "* ```rust - &str + &'static str ``` ___ @@ -8460,12 +8460,12 @@ fn main() { expect![[r#" *r" Hello World "* ```rust - &str + &'static str ``` ___ value of literal: ` Hello World ` -"#]], + "#]], ) } @@ -8480,7 +8480,7 @@ fn main() { expect![[r#" *b"\xF0\x9F\xA6\x80\\"* ```rust - &[u8; 5] + &'static [u8; 5] ``` ___ @@ -8496,7 +8496,7 @@ fn main() { expect![[r#" *br"\xF0\x9F\xA6\x80\\"* ```rust - &[u8; 18] + &'static [u8; 18] ``` ___ @@ -9070,7 +9070,7 @@ struct Pedro$0<'a> { ```rust struct Pedro<'a> { - hola: &str, + hola: &'a str, } ``` @@ -9937,7 +9937,7 @@ fn baz() { --- - `U` = `i32`, `T` = `&str` + `U` = `i32`, `T` = `&'static str` "#]], ); } @@ -10030,7 +10030,7 @@ fn bar() { --- - `T` = `i8`, `U` = `&str` + `T` = `i8`, `U` = `&'static str` "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 52ea2e5ec58b..36fdd90e8aea 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -380,9 +380,9 @@ fn main() { let foo = foo3(); // ^^^ impl Fn(f64, f64) -> u32 let foo = foo4(); - // ^^^ &dyn Fn(f64, f64) -> u32 + // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static) let foo = foo5(); - // ^^^ &dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32 + // ^^^ &'static (dyn Fn(&(dyn Fn(f64, f64) -> u32 + 'static), f64) -> u32 + 'static) let foo = foo6(); // ^^^ impl Fn(f64, f64) -> u32 let foo = foo7(); @@ -413,7 +413,7 @@ fn main() { let foo = foo3(); // ^^^ impl Fn(f64, f64) -> u32 let foo = foo4(); - // ^^^ &dyn Fn(f64, f64) -> u32 + // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static) let foo = foo5(); let foo = foo6(); let foo = foo7(); @@ -528,7 +528,7 @@ fn main() { //^^^^ i32 let _ = 22; let test = "test"; - //^^^^ &str + //^^^^ &'static str let test = InnerStruct {}; //^^^^ InnerStruct @@ -618,12 +618,12 @@ impl Iterator for IntoIter { fn main() { let mut data = Vec::new(); - //^^^^ Vec<&str> + //^^^^ Vec<&'static str> data.push("foo"); for i in data { - //^ &str + //^ &'static str let z = i; - //^ &str + //^ &'static str } } "#, @@ -651,8 +651,8 @@ fn main() { //^^ Vec> let _v = { Vec::>::new() }; //^^ Vec> - let _v = { Vec::>::new() }; - //^^ Vec> + let _v = { Vec::>::new() }; + //^^ Vec> } "#, ); @@ -1017,7 +1017,7 @@ fn test(t: T) { "#, expect![[r#" fn test(t: T) { - let f = |a: i32, b: &str, c: T| {}; + let f = |a: i32, b: &'static str, c: T| {}; let result: () = f(42, "", t); } "#]], diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index de9ca8c000f0..2ec85da4a429 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -194,7 +194,7 @@ impl Tr for () { //^ impl Tr for () impl dyn Tr { } -//^ impl dyn Tr +//^ impl dyn Tr + 'static static S0: () = 0; static S1: () = {}; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 96c2ceef6ba1..f6bcb5642c3b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -1064,7 +1064,7 @@ fn main() { ), work_done_progress_params: Default::default(), }); - assert!(res.to_string().contains("&str")); + assert!(res.to_string().contains("&'static str")); let res = server.send_request::(HoverParams { text_document_position_params: TextDocumentPositionParams::new( @@ -1073,7 +1073,7 @@ fn main() { ), work_done_progress_params: Default::default(), }); - assert!(res.to_string().contains("&str")); + assert!(res.to_string().contains("&'static str")); server.request::( GotoDefinitionParams { From 3eee3dad5c8aa36a88d6ed2e927c53f2ba174819 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 19 Mar 2025 16:11:45 +0300 Subject: [PATCH 080/262] resolve: Support imports of associated types and glob imports from traits --- .../src/error_codes/E0253.md | 6 ++- .../src/hir_ty_lowering/mod.rs | 34 +++++++------ compiler/rustc_resolve/messages.ftl | 7 --- compiler/rustc_resolve/src/diagnostics.rs | 8 ++- compiler/rustc_resolve/src/errors.rs | 16 ------ compiler/rustc_resolve/src/imports.rs | 43 ++++++++-------- compiler/rustc_resolve/src/lib.rs | 10 +--- tests/ui/error-codes/E0253.rs | 10 ---- tests/ui/error-codes/E0253.stderr | 9 ---- ...-gate-import-trait-associated-functions.rs | 3 ++ ...e-import-trait-associated-functions.stderr | 12 ++++- tests/ui/imports/issue-30560.rs | 3 -- tests/ui/imports/issue-30560.stderr | 8 +-- .../use/import_trait_associated_item_bad.rs | 18 +++++++ .../import_trait_associated_item_bad.stderr | 49 +++++++++++++++++++ .../use/import_trait_associated_item_glob.rs | 17 +++++++ tests/ui/use/use-from-trait-xc.rs | 2 +- tests/ui/use/use-from-trait-xc.stderr | 12 +++-- tests/ui/use/use-from-trait.rs | 2 +- tests/ui/use/use-from-trait.stderr | 12 +++-- 20 files changed, 168 insertions(+), 113 deletions(-) delete mode 100644 tests/ui/error-codes/E0253.rs delete mode 100644 tests/ui/error-codes/E0253.stderr create mode 100644 tests/ui/use/import_trait_associated_item_bad.rs create mode 100644 tests/ui/use/import_trait_associated_item_bad.stderr create mode 100644 tests/ui/use/import_trait_associated_item_glob.rs diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index 705d1bfc53e5..628f5e252fbb 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0253.md +++ b/compiler/rustc_error_codes/src/error_codes/E0253.md @@ -1,9 +1,13 @@ +#### Note: this error code is no longer emitted by the compiler. + Attempt was made to import an unimportable type. This can happen when trying to import a type from a trait. Erroneous code example: -```compile_fail,E0253 +``` +#![feature(import_trait_associated_functions)] + mod foo { pub trait MyTrait { type SomeType; 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 fcb7382549f4..5e79e9320153 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1770,7 +1770,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, opt_self_ty: Option>, item_def_id: DefId, - trait_segment: &hir::PathSegment<'tcx>, + trait_segment: Option<&hir::PathSegment<'tcx>>, item_segment: &hir::PathSegment<'tcx>, ) -> Ty<'tcx> { match self.lower_qpath_shared( @@ -1795,7 +1795,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, opt_self_ty: Option>, item_def_id: DefId, - trait_segment: &hir::PathSegment<'tcx>, + trait_segment: Option<&hir::PathSegment<'tcx>>, item_segment: &hir::PathSegment<'tcx>, ) -> Const<'tcx> { match self.lower_qpath_shared( @@ -1820,7 +1820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, opt_self_ty: Option>, item_def_id: DefId, - trait_segment: &hir::PathSegment<'tcx>, + trait_segment: Option<&hir::PathSegment<'tcx>>, item_segment: &hir::PathSegment<'tcx>, assoc_tag: ty::AssocTag, ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> { @@ -1840,7 +1840,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?self_ty); let trait_ref = - self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false); + self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false); debug!(?trait_ref); let item_args = @@ -2196,16 +2196,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } Res::Def(DefKind::AssocTy, def_id) => { - debug_assert!(path.segments.len() >= 2); - let _ = self.prohibit_generic_args( - path.segments[..path.segments.len() - 2].iter(), - GenericsArgsErrExtend::None, - ); + let trait_segment = if let [modules @ .., trait_, _item] = path.segments { + let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None); + Some(trait_) + } else { + None + }; self.lower_qpath_ty( span, opt_self_ty, def_id, - &path.segments[path.segments.len() - 2], + trait_segment, path.segments.last().unwrap(), ) } @@ -2413,16 +2414,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args)) } Res::Def(DefKind::AssocConst, did) => { - debug_assert!(path.segments.len() >= 2); - let _ = self.prohibit_generic_args( - path.segments[..path.segments.len() - 2].iter(), - GenericsArgsErrExtend::None, - ); + let trait_segment = if let [modules @ .., trait_, _item] = path.segments { + let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None); + Some(trait_) + } else { + None + }; self.lower_qpath_const( span, opt_self_ty, did, - &path.segments[path.segments.len() - 2], + trait_segment, path.segments.last().unwrap(), ) } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 558a01713dc7..38cdfa72a14d 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -218,10 +218,6 @@ resolve_invalid_asm_sym = .label = is a local variable .help = `sym` operands must refer to either a function or a static -resolve_is_not_directly_importable = - `{$target}` is not directly importable - .label = cannot be imported directly - resolve_is_private = {$ident_descr} `{$ident}` is private .label = private {$ident_descr} @@ -231,9 +227,6 @@ resolve_item_was_behind_feature = resolve_item_was_cfg_out = the item is gated here -resolve_items_in_traits_are_not_importable = - items in traits are not importable - resolve_label_with_similar_name_reachable = a label with a similar name is reachable diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 363a75911ad4..74daad083946 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1181,11 +1181,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } { let in_module_is_extern = !in_module.def_id().is_local(); in_module.for_each_child(self, |this, ident, ns, name_binding| { - // avoid non-importable candidates - if !name_binding.is_importable() - // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable - || name_binding.is_assoc_const_or_fn() - && !this.tcx.features().import_trait_associated_functions() + // Avoid non-importable candidates. + if name_binding.is_assoc_item() + && !this.tcx.features().import_trait_associated_functions() { return; } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index e26b300f13ef..7fe74378b674 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -781,22 +781,6 @@ pub(crate) struct CannotGlobImportAllCrates { pub(crate) span: Span, } -#[derive(Diagnostic)] -#[diag(resolve_items_in_traits_are_not_importable)] -pub(crate) struct ItemsInTraitsAreNotImportable { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Diagnostic)] -#[diag(resolve_is_not_directly_importable, code = E0253)] -pub(crate) struct IsNotDirectlyImportable { - #[primary_span] - #[label] - pub(crate) span: Span, - pub(crate) target: Ident, -} - #[derive(Subdiagnostic)] #[suggestion( resolve_unexpected_res_change_ty_to_const_param_sugg, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 762e08b2be5f..816efd0d5fa2 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -30,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates}; use crate::errors::{ CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, - ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable, - ItemsInTraitsAreNotImportable, + ConsiderAddingMacroExport, ConsiderMarkingAsPub, }; use crate::{ AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module, @@ -835,11 +834,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let parent = import.parent_scope.module; match source_bindings[ns].get() { - Err(Undetermined) => indeterminate_count += 1, - // Don't update the resolution, because it was never added. - Err(Determined) if target.name == kw::Underscore => {} - Ok(binding) if binding.is_importable() => { - if binding.is_assoc_const_or_fn() + Ok(binding) => { + if binding.is_assoc_item() && !this.tcx.features().import_trait_associated_functions() { feature_err( @@ -850,21 +846,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) .emit(); } + let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); } - source_binding @ (Ok(..) | Err(Determined)) => { - if source_binding.is_ok() { - this.dcx() - .create_err(IsNotDirectlyImportable { span: import.span, target }) - .emit(); + Err(Determined) => { + // Don't update the resolution for underscores, because it was never added. + if target.name != kw::Underscore { + let key = BindingKey::new(target, ns); + this.update_resolution(parent, key, false, |_, resolution| { + resolution.single_imports.swap_remove(&import); + }); } - let key = BindingKey::new(target, ns); - this.update_resolution(parent, key, false, |_, resolution| { - resolution.single_imports.swap_remove(&import); - }); } + Err(Undetermined) => indeterminate_count += 1, } } }); @@ -1428,10 +1424,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; }; - if module.is_trait() { - self.dcx().emit_err(ItemsInTraitsAreNotImportable { span: import.span }); - return; - } else if module == import.parent_scope.module { + if module.is_trait() && !self.tcx.features().import_trait_associated_functions() { + feature_err( + self.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } + + if module == import.parent_scope.module { return; } else if is_prelude { self.prelude = Some(module); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index d2da3ac7d86f..d23e588e2e3d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -949,14 +949,8 @@ impl<'ra> NameBindingData<'ra> { } } - fn is_importable(&self) -> bool { - !matches!(self.res(), Res::Def(DefKind::AssocTy, _)) - } - - // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless - // the feature `import_trait_associated_functions` is enable - fn is_assoc_const_or_fn(&self) -> bool { - matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _)) + fn is_assoc_item(&self) -> bool { + matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _)) } fn macro_kind(&self) -> Option { diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs deleted file mode 100644 index 8284f791c648..000000000000 --- a/tests/ui/error-codes/E0253.rs +++ /dev/null @@ -1,10 +0,0 @@ -mod foo { - pub trait MyTrait { - type SomeType; - } -} - -use foo::MyTrait::SomeType; - //~^ ERROR E0253 - -fn main() {} diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr deleted file mode 100644 index 954dbc816939..000000000000 --- a/tests/ui/error-codes/E0253.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0253]: `SomeType` is not directly importable - --> $DIR/E0253.rs:7:5 - | -LL | use foo::MyTrait::SomeType; - | ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0253`. diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs index aec13fb02028..c2c010eaba63 100644 --- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs @@ -60,4 +60,7 @@ fn f() { let t: Option = DEFAULT; } +trait Glob {} +use Glob::*; //~ ERROR `use` associated items of traits is unstable + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr index d342f5bd5512..fca3cef3e203 100644 --- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr @@ -48,6 +48,16 @@ LL | use super::A::{self, DEFAULT, new}; = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 5 previous errors +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:64:5 + | +LL | use Glob::*; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/imports/issue-30560.rs b/tests/ui/imports/issue-30560.rs index d8d4ca608f1c..fe5d17c18736 100644 --- a/tests/ui/imports/issue-30560.rs +++ b/tests/ui/imports/issue-30560.rs @@ -3,7 +3,4 @@ use Alias::*; //~ ERROR unresolved import `Alias` [E0432] use std::io::Result::*; //~ ERROR unresolved import `std::io::Result` [E0432] -trait T {} -use T::*; //~ ERROR items in traits are not importable - fn main() {} diff --git a/tests/ui/imports/issue-30560.stderr b/tests/ui/imports/issue-30560.stderr index 69cfd4c06a8b..89492261cbaf 100644 --- a/tests/ui/imports/issue-30560.stderr +++ b/tests/ui/imports/issue-30560.stderr @@ -1,9 +1,3 @@ -error: items in traits are not importable - --> $DIR/issue-30560.rs:7:5 - | -LL | use T::*; - | ^^^^ - error[E0432]: unresolved import `Alias` --> $DIR/issue-30560.rs:2:5 | @@ -16,6 +10,6 @@ error[E0432]: unresolved import `std::io::Result` LL | use std::io::Result::*; | ^^^^^^ `Result` is a type alias, not a module -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/use/import_trait_associated_item_bad.rs b/tests/ui/use/import_trait_associated_item_bad.rs new file mode 100644 index 000000000000..d3d2a8e83cdd --- /dev/null +++ b/tests/ui/use/import_trait_associated_item_bad.rs @@ -0,0 +1,18 @@ +#![feature(import_trait_associated_functions)] +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +trait Trait { + type AssocTy; + const CONST: usize; +} + +use Trait::AssocTy; +type Alias1 = AssocTy; //~ ERROR ambiguous associated type +type Alias2 = self::AssocTy; //~ ERROR ambiguous associated type + +use Trait::CONST; +type Alias3 = [u8; CONST]; //~ ERROR ambiguous associated constant +type Alias4 = [u8; self::CONST]; //~ ERROR ambiguous associated constant + +fn main() {} diff --git a/tests/ui/use/import_trait_associated_item_bad.stderr b/tests/ui/use/import_trait_associated_item_bad.stderr new file mode 100644 index 000000000000..d5cd5d37bd71 --- /dev/null +++ b/tests/ui/use/import_trait_associated_item_bad.stderr @@ -0,0 +1,49 @@ +error[E0223]: ambiguous associated type + --> $DIR/import_trait_associated_item_bad.rs:11:15 + | +LL | type Alias1 = AssocTy; + | ^^^^^^^ + | +help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path + | +LL | type Alias1 = ::AssocTy; + | ++++++++++++++++++++ + +error[E0223]: ambiguous associated type + --> $DIR/import_trait_associated_item_bad.rs:12:15 + | +LL | type Alias2 = self::AssocTy; + | ^^^^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path + | +LL - type Alias2 = self::AssocTy; +LL + type Alias2 = ::AssocTy; + | + +error[E0223]: ambiguous associated constant + --> $DIR/import_trait_associated_item_bad.rs:15:20 + | +LL | type Alias3 = [u8; CONST]; + | ^^^^^ + | +help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path + | +LL | type Alias3 = [u8; ::CONST]; + | ++++++++++++++++++++ + +error[E0223]: ambiguous associated constant + --> $DIR/import_trait_associated_item_bad.rs:16:20 + | +LL | type Alias4 = [u8; self::CONST]; + | ^^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path + | +LL - type Alias4 = [u8; self::CONST]; +LL + type Alias4 = [u8; ::CONST]; + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/use/import_trait_associated_item_glob.rs b/tests/ui/use/import_trait_associated_item_glob.rs new file mode 100644 index 000000000000..8a712514ed59 --- /dev/null +++ b/tests/ui/use/import_trait_associated_item_glob.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![feature(import_trait_associated_functions)] + +trait Trait: Default { + fn f() -> Self { Default::default() } + fn g() -> Self { Default::default() } +} + +impl Trait for u8 {} + +use Trait::*; + +fn main() { + let _: u8 = f(); + let _: u8 = g(); +} diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs index b030892aa269..220bf8cad46f 100644 --- a/tests/ui/use/use-from-trait-xc.rs +++ b/tests/ui/use/use-from-trait-xc.rs @@ -6,7 +6,7 @@ use use_from_trait_xc::Trait::foo; //~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Trait::Assoc; -//~^ ERROR `Assoc` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Trait::CONST; //~^ ERROR `use` associated items of traits is unstable [E0658] diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr index 0f8440aa5307..c8ee29b18d0c 100644 --- a/tests/ui/use/use-from-trait-xc.stderr +++ b/tests/ui/use/use-from-trait-xc.stderr @@ -8,11 +8,15 @@ LL | use use_from_trait_xc::Trait::foo; = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0253]: `Assoc` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:8:5 | LL | use use_from_trait_xc::Trait::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:11:5 @@ -74,5 +78,5 @@ LL | struct Foo; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0253, E0432, E0603, E0658. -For more information about an error, try `rustc --explain E0253`. +Some errors have detailed explanations: E0432, E0603, E0658. +For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs index 89b7aaa4ba38..cab661a29e8e 100644 --- a/tests/ui/use/use-from-trait.rs +++ b/tests/ui/use/use-from-trait.rs @@ -1,5 +1,5 @@ use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658] -use Trait::Assoc; //~ ERROR `Assoc` is not directly importable +use Trait::Assoc; //~ ERROR `use` associated items of traits is unstable [E0658] use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658] use Foo::new; //~ ERROR unresolved import `Foo` [E0432] diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr index 2dd78a354529..63cfcc207504 100644 --- a/tests/ui/use/use-from-trait.stderr +++ b/tests/ui/use/use-from-trait.stderr @@ -8,11 +8,15 @@ LL | use Trait::foo; = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0253]: `Assoc` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:2:5 | LL | use Trait::Assoc; - | ^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:3:5 @@ -38,5 +42,5 @@ LL | use Foo::C2; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0253, E0432, E0658. -For more information about an error, try `rustc --explain E0253`. +Some errors have detailed explanations: E0432, E0658. +For more information about an error, try `rustc --explain E0432`. From 842858f7650cae36d1b7194e4c758f42b2ca700c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 30 Apr 2025 13:02:45 +0300 Subject: [PATCH 081/262] linker: Quote symbol names in .def files To support weird symbol names, including dots in particular. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 4 +++- tests/ui/linking/weird-export-names.rs | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/ui/linking/weird-export-names.rs diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index a09eec5dd74b..e1f903726fbd 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -816,7 +816,9 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, "EXPORTS")?; for symbol in symbols { debug!(" _{symbol}"); - writeln!(f, " {symbol}")?; + // Quote the name in case it's reserved by linker in some way + // (this accounts for names with dots in particular). + writeln!(f, " \"{symbol}\"")?; } }; if let Err(error) = res { diff --git a/tests/ui/linking/weird-export-names.rs b/tests/ui/linking/weird-export-names.rs new file mode 100644 index 000000000000..8fb2dc6bf5e8 --- /dev/null +++ b/tests/ui/linking/weird-export-names.rs @@ -0,0 +1,10 @@ +//@ build-pass +//@ needs-crate-type: cdylib + +#![crate_type = "cdylib"] + +#[export_name = "foo.0123"] +pub extern "C" fn foo() {} + +#[export_name = "EXPORTS"] +pub extern "C" fn bar() {} From 6a48217efc1e5874eda45ac7a1af6c3a12fe7d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 2 May 2025 14:55:36 +0200 Subject: [PATCH 082/262] Move `DisambiguatorState` into `intern_const_alloc_recursive` --- .../src/const_eval/dummy_machine.rs | 4 +- .../src/const_eval/machine.rs | 5 +-- .../rustc_const_eval/src/interpret/intern.rs | 37 +++++++++++++------ .../rustc_const_eval/src/interpret/util.rs | 5 +-- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index dc5f84adb76f..46dcebc46e9c 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -1,5 +1,3 @@ -use rustc_hir::def_id::LocalDefId; -use rustc_hir::definitions::DisambiguatorState; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult}; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; @@ -44,7 +42,7 @@ pub macro throw_machine_stop_str($($tt:tt)*) {{ pub struct DummyMachine; impl HasStaticRootDefId for DummyMachine { - fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> { + fn static_def_id(&self) -> Option { None } } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index dddfc6a4e092..61a7ec13511c 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -6,7 +6,6 @@ use rustc_abi::{Align, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem}; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; @@ -64,7 +63,7 @@ pub struct CompileTimeMachine<'tcx> { /// If `Some`, we are evaluating the initializer of the static with the given `LocalDefId`, /// storing the result in the given `AllocId`. /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops. - pub(crate) static_root_ids: Option<(AllocId, LocalDefId, DisambiguatorState)>, + pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>, /// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes). union_data_ranges: FxHashMap, RangeSet>, @@ -707,7 +706,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> { // Check if this is the currently evaluated static. - if Some(alloc_id) == ecx.machine.static_root_ids.as_ref().map(|(id, ..)| *id) { + if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { return Err(ConstEvalErrKind::RecursiveStatic).into(); } // If this is another static, make sure we fire off the query to detect cycles. diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 47cc2d49fe27..1dd96297d1fd 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -46,13 +46,12 @@ pub trait CompileTimeMachine<'tcx, T> = Machine< pub trait HasStaticRootDefId { /// Returns the `DefId` of the static item that is currently being evaluated. /// Used for interning to be able to handle nested allocations. - fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)>; + fn static_def_id(&self) -> Option; } impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> { - fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> { - let (_, static_id, d) = self.static_root_ids.as_mut()?; - Some((*static_id, d)) + fn static_def_id(&self) -> Option { + Some(self.static_root_ids?.1) } } @@ -67,6 +66,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, + disambiguator: Option<&mut DisambiguatorState>, ) -> Result + 'tcx, ()> { trace!("intern_shallow {:?}", alloc_id); // remove allocation @@ -88,8 +88,14 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( } // link the alloc id to the actual allocation let alloc = ecx.tcx.mk_const_alloc(alloc); - if let Some((static_id, disambiguator)) = ecx.machine.static_parent_and_disambiguator() { - intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc, disambiguator); + if let Some(static_id) = ecx.machine.static_def_id() { + intern_as_new_static( + ecx.tcx, + static_id, + alloc_id, + alloc, + disambiguator.expect("disambiguator needed"), + ); } else { ecx.tcx.set_alloc_id_memory(alloc_id, alloc); } @@ -105,6 +111,10 @@ fn intern_as_new_static<'tcx>( alloc: ConstAllocation<'tcx>, disambiguator: &mut DisambiguatorState, ) { + // `intern_const_alloc_recursive` is called once per static and it contains the `DisambiguatorState`. + // The `::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the + // `DisambiguatorState` ensures the generated path is unique for this call as we generate + // `::{{nested#n}}` where `n` is the `n`th `intern_as_new_static` call. let feed = tcx.create_def( static_id, None, @@ -158,6 +168,8 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval intern_kind: InternKind, ret: &MPlaceTy<'tcx>, ) -> Result<(), InternResult> { + let mut disambiguator = DisambiguatorState::new(); + // We are interning recursively, and for mutability we are distinguishing the "root" allocation // that we are starting in, and all other allocations that we are encountering recursively. let (base_mutability, inner_mutability, is_static) = match intern_kind { @@ -201,7 +213,9 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval alloc.1.mutability = base_mutability; alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() } else { - intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().collect() + intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguator)) + .unwrap() + .collect() }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. @@ -295,7 +309,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval // okay with losing some potential for immutability here. This can anyway only affect // `static mut`. just_interned.insert(alloc_id); - match intern_shallow(ecx, alloc_id, inner_mutability) { + match intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator)) { Ok(nested) => todo.extend(nested), Err(()) => { ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning"); @@ -317,8 +331,9 @@ pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>> return interp_ok(()); } // Move allocation to `tcx`. - if let Some(_) = - (intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))?).next() + if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not, None) + .map_err(|()| err_ub!(DeadLocal))? + .next() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a @@ -344,7 +359,7 @@ impl<'tcx> InterpCx<'tcx, DummyMachine> { let dest = self.allocate(layout, MemoryKind::Stack)?; f(self, &dest.clone().into())?; let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance - for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() { + for prov in intern_shallow(self, alloc_id, Mutability::Not, None).unwrap() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a // proper recursive interning loop -- or just call `intern_const_alloc_recursive`. diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index faaa2bd24bbd..ba579e25f036 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,4 @@ use rustc_hir::def_id::LocalDefId; -use rustc_hir::definitions::DisambiguatorState; use rustc_middle::mir; use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; @@ -41,8 +40,8 @@ pub(crate) fn create_static_alloc<'tcx>( ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit)?; let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into()); - assert!(ecx.machine.static_root_ids.is_none()); - ecx.machine.static_root_ids = Some((alloc_id, static_def_id, DisambiguatorState::new())); + assert_eq!(ecx.machine.static_root_ids, None); + ecx.machine.static_root_ids = Some((alloc_id, static_def_id)); assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none()); interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout)) } From a8fb9d0979ae883967c23e956b617774b8c4a000 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 2 May 2025 17:26:48 +0200 Subject: [PATCH 083/262] refactor: Simplify macro call id construction --- src/tools/rust-analyzer/Cargo.toml | 1 + .../crates/hir-def/src/expr_store/expander.rs | 31 +++++- .../rust-analyzer/crates/hir-def/src/lib.rs | 99 ++----------------- .../hir-def/src/macro_expansion_tests/mbe.rs | 10 +- .../hir-def/src/macro_expansion_tests/mod.rs | 85 ++++++++-------- .../crates/hir-def/src/nameres/assoc.rs | 18 ++-- .../crates/hir-def/src/nameres/collector.rs | 42 +++----- .../rust-analyzer/crates/syntax/Cargo.toml | 2 +- 8 files changed, 113 insertions(+), 175 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index dd39cf59bb44..c4c2fdf34bae 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -131,6 +131,7 @@ process-wrap = { version = "8.2.0", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.6", default-features = false } rayon = "1.10.0" +rowan = "=0.15.15" salsa = { version = "0.21.1", default-features = false, features = ["rayon","salsa_unstable"] } salsa-macros = "0.21.1" semver = "1.0.26" diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs index d24f4b7028d7..3823fb5a1e75 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs @@ -5,20 +5,22 @@ use std::mem; use base_db::Crate; use cfg::CfgOptions; use drop_bomb::DropBomb; +use hir_expand::AstId; use hir_expand::{ ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId, eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap, }; use span::{AstIdMap, Edition, SyntaxContext}; use syntax::ast::HasAttrs; -use syntax::{Parse, ast}; +use syntax::{AstNode, Parse, ast}; use triomphe::Arc; use tt::TextRange; use crate::attr::Attrs; use crate::expr_store::HygieneId; +use crate::macro_call_as_call_id; use crate::nameres::DefMap; -use crate::{AsMacroCall, MacroId, UnresolvedMacro, db::DefDatabase}; +use crate::{MacroId, UnresolvedMacro, db::DefDatabase}; #[derive(Debug)] pub(super) struct Expander { @@ -92,8 +94,31 @@ impl Expander { let result = self.within_limit(db, |this| { let macro_call = this.in_file(¯o_call); - match macro_call.as_call_id_with_errors( + + let expands_to = hir_expand::ExpandTo::from_call_site(macro_call.value); + let ast_id = AstId::new(macro_call.file_id, this.ast_id_map().ast_id(macro_call.value)); + let path = macro_call.value.path().and_then(|path| { + let range = path.syntax().text_range(); + let mod_path = ModPath::from_src(db, path, &mut |range| { + this.span_map.span_for_range(range).ctx + })?; + let call_site = this.span_map.span_for_range(range); + Some((call_site, mod_path)) + }); + + let Some((call_site, path)) = path else { + return ExpandResult::only_err(ExpandError::other( + this.span_map.span_for_range(macro_call.value.syntax().text_range()), + "malformed macro invocation", + )); + }; + + match macro_call_as_call_id( db, + ast_id, + &path, + call_site.ctx, + expands_to, krate, |path| resolver(path).map(|it| db.macro_def(it)), eager_callback, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index cf65e6355925..28011bda7c54 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -64,8 +64,8 @@ use std::hash::{Hash, Hasher}; use base_db::{Crate, impl_intern_key}; use hir_expand::{ - AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, - MacroDefId, MacroDefKind, + AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, + MacroDefKind, builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, eager::expand_eager_macro_input, @@ -79,7 +79,7 @@ use la_arena::Idx; use nameres::DefMap; use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::impl_from; -use syntax::{AstNode, ast}; +use syntax::ast; pub use hir_expand::{Intern, Lookup, tt}; @@ -1166,66 +1166,6 @@ impl ModuleDefId { }) } } - -// FIXME: Replace this with a plain function, it only has one impl -/// A helper trait for converting to MacroCallId -trait AsMacroCall { - fn as_call_id_with_errors( - &self, - db: &dyn ExpandDatabase, - krate: Crate, - resolver: impl Fn(&ModPath) -> Option + Copy, - eager_callback: &mut dyn FnMut( - InFile<(syntax::AstPtr, span::FileAstId)>, - MacroCallId, - ), - ) -> Result>, UnresolvedMacro>; -} - -impl AsMacroCall for InFile<&ast::MacroCall> { - fn as_call_id_with_errors( - &self, - db: &dyn ExpandDatabase, - krate: Crate, - resolver: impl Fn(&ModPath) -> Option + Copy, - eager_callback: &mut dyn FnMut( - InFile<(syntax::AstPtr, span::FileAstId)>, - MacroCallId, - ), - ) -> Result>, UnresolvedMacro> { - let expands_to = hir_expand::ExpandTo::from_call_site(self.value); - let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); - let span_map = db.span_map(self.file_id); - let path = self.value.path().and_then(|path| { - let range = path.syntax().text_range(); - let mod_path = ModPath::from_src(db, path, &mut |range| { - span_map.as_ref().span_for_range(range).ctx - })?; - let call_site = span_map.span_for_range(range); - Some((call_site, mod_path)) - }); - - let Some((call_site, path)) = path else { - return Ok(ExpandResult::only_err(ExpandError::other( - span_map.span_for_range(self.value.syntax().text_range()), - "malformed macro invocation", - ))); - }; - - macro_call_as_call_id_with_eager( - db, - ast_id, - &path, - call_site.ctx, - expands_to, - krate, - resolver, - resolver, - eager_callback, - ) - } -} - /// Helper wrapper for `AstId` with `ModPath` #[derive(Clone, Debug, Eq, PartialEq)] struct AstIdWithPath { @@ -1239,41 +1179,14 @@ impl AstIdWithPath { } } -fn macro_call_as_call_id( - db: &dyn ExpandDatabase, - call: &AstIdWithPath, - call_site: SyntaxContext, - expand_to: ExpandTo, - krate: Crate, - resolver: impl Fn(&ModPath) -> Option + Copy, - eager_callback: &mut dyn FnMut( - InFile<(syntax::AstPtr, span::FileAstId)>, - MacroCallId, - ), -) -> Result, UnresolvedMacro> { - macro_call_as_call_id_with_eager( - db, - call.ast_id, - &call.path, - call_site, - expand_to, - krate, - resolver, - resolver, - eager_callback, - ) - .map(|res| res.value) -} - -fn macro_call_as_call_id_with_eager( +pub fn macro_call_as_call_id( db: &dyn ExpandDatabase, ast_id: AstId, path: &ModPath, call_site: SyntaxContext, expand_to: ExpandTo, krate: Crate, - resolver: impl FnOnce(&ModPath) -> Option, - eager_resolver: impl Fn(&ModPath) -> Option, + resolver: impl Fn(&ModPath) -> Option + Copy, eager_callback: &mut dyn FnMut( InFile<(syntax::AstPtr, span::FileAstId)>, MacroCallId, @@ -1289,7 +1202,7 @@ fn macro_call_as_call_id_with_eager( ast_id, def, call_site, - &|path| eager_resolver(path).filter(MacroDefId::is_fn_like), + &|path| resolver(path).filter(MacroDefId::is_fn_like), eager_callback, ), _ if def.is_fn_like() => ExpandResult { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs index abb5bd5ed726..38fc4b3d118a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -2001,8 +2001,9 @@ macro_rules! bug { true }; } - -let _ = bug!(a;;;test); +fn f() { + let _ = bug!(a;;;test); +} "#, expect![[r#" macro_rules! bug { @@ -2022,8 +2023,9 @@ macro_rules! bug { true }; } - -let _ = true; +fn f() { + let _ = true; +} "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 143b5df77305..800c96ebdae0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -19,7 +19,7 @@ use std::{iter, ops::Range, sync}; use base_db::RootQueryDb; use expect_test::Expect; use hir_expand::{ - InFile, MacroCallKind, MacroKind, + AstId, InFile, MacroCallId, MacroCallKind, MacroKind, db::ExpandDatabase, proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind}, span_map::SpanMapRef, @@ -29,7 +29,7 @@ use itertools::Itertools; use span::{Edition, Span}; use stdx::{format_to, format_to_acc}; use syntax::{ - AstNode, + AstNode, AstPtr, SyntaxKind::{COMMENT, EOF, IDENT, LIFETIME_IDENT}, SyntaxNode, T, ast::{self, edit::IndentLevel}, @@ -37,10 +37,9 @@ use syntax::{ use test_fixture::WithFixture; use crate::{ - AdtId, AsMacroCall, Lookup, ModuleDefId, + AdtId, Lookup, ModuleDefId, db::DefDatabase, - nameres::{DefMap, MacroSubNs, ModuleSource}, - resolver::HasResolver, + nameres::{DefMap, ModuleSource}, src::HasSource, test_db::TestDB, tt::TopSubtree, @@ -78,7 +77,6 @@ fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) expect.assert_eq(&errors); } -#[track_caller] fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) { let extra_proc_macros = vec![( r#" @@ -95,54 +93,59 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream disabled: false, }, )]; + + fn resolve( + db: &dyn DefDatabase, + def_map: &DefMap, + ast_id: AstId, + ast_ptr: InFile>, + ) -> Option { + def_map.modules().find_map(|module| { + for decl in + module.1.scope.declarations().chain(module.1.scope.unnamed_consts().map(Into::into)) + { + let body = match decl { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => continue, + }; + + let (body, sm) = db.body_with_source_map(body); + if let Some(it) = + body.blocks(db).find_map(|block| resolve(db, &block.1, ast_id, ast_ptr)) + { + return Some(it); + } + if let Some((_, res)) = sm.macro_calls().find(|it| it.0 == ast_ptr) { + return Some(res); + } + } + module.1.scope.macro_invoc(ast_id) + }) + } + let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros); let krate = db.fetch_test_crate(); let def_map = db.crate_def_map(krate); let local_id = DefMap::ROOT; - let module = def_map.module_id(local_id); - let resolver = module.resolver(&db); let source = def_map[local_id].definition_source(&db); let source_file = match source.value { ModuleSource::SourceFile(it) => it, ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(), }; - // What we want to do is to replace all macros (fn-like, derive, attr) with - // their expansions. Turns out, we don't actually store enough information - // to do this precisely though! Specifically, if a macro expands to nothing, - // it leaves zero traces in def-map, so we can't get its expansion after the - // fact. - // - // This is the usual - // - // resolve/record tension! - // - // So here we try to do a resolve, which is necessary a heuristic. For macro - // calls, we use `as_call_id_with_errors`. For derives, we look at the impls - // in the module and assume that, if impls's source is a different - // `HirFileId`, than it came from macro expansion. - let mut text_edits = Vec::new(); let mut expansions = Vec::new(); - for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) { - let macro_call = InFile::new(source.file_id, ¯o_call); - let res = macro_call - .as_call_id_with_errors( - &db, - krate, - |path| { - resolver - .resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang)) - .map(|(it, _)| db.macro_def(it)) - }, - &mut |_, _| (), - ) - .unwrap(); - let macro_call_id = res.value.unwrap(); - let mut expansion_result = db.parse_macro_expansion(macro_call_id); - expansion_result.err = expansion_result.err.or(res.err); - expansions.push((macro_call.value.clone(), expansion_result)); + for macro_call_node in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) { + let ast_id = db.ast_id_map(source.file_id).ast_id(¯o_call_node); + let ast_id = InFile::new(source.file_id, ast_id); + let ptr = InFile::new(source.file_id, AstPtr::new(¯o_call_node)); + let macro_call_id = resolve(&db, &def_map, ast_id, ptr) + .unwrap_or_else(|| panic!("unable to find semantic macro call {macro_call_node}")); + let expansion_result = db.parse_macro_expansion(macro_call_id); + expansions.push((macro_call_node.clone(), expansion_result)); } for (call, exp) in expansions.into_iter().rev() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs index b09706552947..448b908936a2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs @@ -259,7 +259,8 @@ impl<'a> AssocItemCollector<'a> { }; match macro_call_as_call_id( self.db, - &AstIdWithPath::new(tree_id.file_id(), ast_id, Clone::clone(path)), + InFile::new(tree_id.file_id(), ast_id), + path, ctxt, expand_to, self.module_id.krate(), @@ -268,12 +269,15 @@ impl<'a> AssocItemCollector<'a> { self.macro_calls.push((ptr.map(|(_, it)| it.upcast()), call_id)) }, ) { - Ok(Some(call_id)) => { - self.macro_calls - .push((InFile::new(tree_id.file_id(), ast_id.upcast()), call_id)); - self.collect_macro_items(call_id); - } - Ok(None) => (), + // FIXME: Expansion error? + Ok(call_id) => match call_id.value { + Some(call_id) => { + self.macro_calls + .push((InFile::new(tree_id.file_id(), ast_id.upcast()), call_id)); + self.collect_macro_items(call_id); + } + None => (), + }, Err(_) => { self.diagnostics.push(DefDiagnostic::unresolved_macro_call( self.module_id.local_id, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 77effbcc8800..8df0f092cd0b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -39,7 +39,7 @@ use crate::{ ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind, }, - macro_call_as_call_id, macro_call_as_call_id_with_eager, + macro_call_as_call_id, nameres::{ BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, ModuleOrigin, ResolveMode, attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id}, @@ -1256,7 +1256,8 @@ impl DefCollector<'_> { MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => { let call_id = macro_call_as_call_id( self.db, - ast_id, + ast_id.ast_id, + &ast_id.path, *call_site, *expand_to, self.def_map.krate, @@ -1265,15 +1266,18 @@ impl DefCollector<'_> { eager_callback_buffer.push((directive.module_id, ptr, call_id)); }, ); - if let Ok(Some(call_id)) = call_id { - self.def_map.modules[directive.module_id] - .scope - .add_macro_invoc(ast_id.ast_id, call_id); + if let Ok(call_id) = call_id { + // FIXME: Expansion error + if let Some(call_id) = call_id.value { + self.def_map.modules[directive.module_id] + .scope + .add_macro_invoc(ast_id.ast_id, call_id); - push_resolved(directive, call_id); + push_resolved(directive, call_id); - res = ReachedFixedPoint::No; - return Resolved::Yes; + res = ReachedFixedPoint::No; + return Resolved::Yes; + } } } MacroDirectiveKind::Derive { @@ -1542,7 +1546,8 @@ impl DefCollector<'_> { // FIXME: we shouldn't need to re-resolve the macro here just to get the unresolved error! let macro_call_as_call_id = macro_call_as_call_id( self.db, - ast_id, + ast_id.ast_id, + &ast_id.path, *call_site, *expand_to, self.def_map.krate, @@ -2420,7 +2425,7 @@ impl ModCollector<'_, '_> { let mut eager_callback_buffer = vec![]; // Case 1: try to resolve macro calls with single-segment name and expand macro_rules - if let Ok(res) = macro_call_as_call_id_with_eager( + if let Ok(res) = macro_call_as_call_id( db, ast_id.ast_id, &ast_id.path, @@ -2445,21 +2450,6 @@ impl ModCollector<'_, '_> { .map(|it| self.def_collector.db.macro_def(it)) }) }, - |path| { - let resolved_res = self.def_collector.def_map.resolve_path_fp_with_macro( - self.def_collector - .crate_local_def_map - .as_deref() - .unwrap_or(&self.def_collector.local_def_map), - db, - ResolveMode::Other, - self.module_id, - path, - BuiltinShadowMode::Module, - Some(MacroSubNs::Bang), - ); - resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it)) - }, &mut |ptr, call_id| eager_callback_buffer.push((ptr, call_id)), ) { for (ptr, call_id) in eager_callback_buffer { diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml index 510d44d00917..4c7704803ef3 100644 --- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml @@ -14,7 +14,7 @@ rust-version.workspace = true [dependencies] either.workspace = true itertools.workspace = true -rowan = "=0.15.15" +rowan.workspace = true rustc-hash.workspace = true rustc-literal-escaper.workspace = true smol_str.workspace = true From 9eb1e83a12121302dd5ae09c7ba419de08e2da34 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sat, 3 May 2025 00:31:33 +0900 Subject: [PATCH 084/262] fix: Correct assoc ty bound var starting index --- .../crates/hir-ty/src/chalk_db.rs | 5 +++- .../crates/hir-ty/src/tests/regression.rs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 376daccbdae8..cd799c03ddf7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -637,7 +637,10 @@ pub(crate) fn associated_ty_data_query( .fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, 0) .build(); let pro_ty = TyBuilder::assoc_type_projection(db, type_alias, Some(trait_subst)) - .fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, generic_params.len_self()) + .fill_with_bound_vars( + crate::DebruijnIndex::INNERMOST, + generic_params.parent_generics().map_or(0, |it| it.len()), + ) .build(); let self_ty = TyKind::Alias(AliasTy::Projection(pro_ty)).intern(Interner); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 644b0d392bcf..47c695c69748 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2278,3 +2278,26 @@ fn test(x: bool) { "#]], ); } + +#[test] +fn issue_19730() { + check_infer( + r#" +trait Trait {} + +trait Foo { + type Bar: Trait; + + fn foo(bar: Self::Bar) { + let _ = bar; + } +} +"#, + expect![[r#" + 83..86 'bar': Foo::Bar + 105..133 '{ ... }': () + 119..120 '_': Foo::Bar + 123..126 'bar': Foo::Bar + "#]], + ); +} From 867b4c9e489c71246915ebe3e1ceddef66d760a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 2 May 2025 13:26:35 +0200 Subject: [PATCH 085/262] Test that names of variables in external macros are not shown on a borrow error --- .../rustc_borrowck/src/diagnostics/mod.rs | 8 +++++ .../auxiliary/return_from_external_macro.rs | 11 +++++++ tests/ui/macros/return_from_external_macro.rs | 17 +++++++++++ .../macros/return_from_external_macro.stderr | 29 +++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 tests/ui/macros/auxiliary/return_from_external_macro.rs create mode 100644 tests/ui/macros/return_from_external_macro.rs create mode 100644 tests/ui/macros/return_from_external_macro.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index f9f63ae92a84..5e3f3ffa2ea8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -317,6 +317,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { opt: DescribePlaceOpt, ) -> Option { let local = place.local; + if self.body.local_decls[local] + .source_info + .span + .in_external_macro(self.infcx.tcx.sess.source_map()) + { + return None; + } + let mut autoderef_index = None; let mut buf = String::new(); let mut ok = self.append_local_to_string(local, &mut buf); diff --git a/tests/ui/macros/auxiliary/return_from_external_macro.rs b/tests/ui/macros/auxiliary/return_from_external_macro.rs new file mode 100644 index 000000000000..df59d8bdcb0d --- /dev/null +++ b/tests/ui/macros/auxiliary/return_from_external_macro.rs @@ -0,0 +1,11 @@ +#![feature(super_let)] + +#[macro_export] +macro_rules! foo { + () => { + { + super let args = 1; + &args + } + }; +} diff --git a/tests/ui/macros/return_from_external_macro.rs b/tests/ui/macros/return_from_external_macro.rs new file mode 100644 index 000000000000..43fe99e63add --- /dev/null +++ b/tests/ui/macros/return_from_external_macro.rs @@ -0,0 +1,17 @@ +//@ aux-crate: ret_from_ext=return_from_external_macro.rs + +#![feature(super_let)] +extern crate ret_from_ext; + +fn foo() -> impl Sized { + drop(|| ret_from_ext::foo!()); + //~^ ERROR cannot return reference to local binding + + ret_from_ext::foo!() + //~^ ERROR temporary value dropped while borrowed +} +//~^ NOTE temporary value is freed at the end of this statement + +fn main() { + foo(); +} diff --git a/tests/ui/macros/return_from_external_macro.stderr b/tests/ui/macros/return_from_external_macro.stderr new file mode 100644 index 000000000000..b6010b8ec793 --- /dev/null +++ b/tests/ui/macros/return_from_external_macro.stderr @@ -0,0 +1,29 @@ +error[E0515]: cannot return reference to local binding + --> $DIR/return_from_external_macro.rs:7:13 + | +LL | drop(|| ret_from_ext::foo!()); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | returns a reference to data owned by the current function + | local binding introduced here + | + = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0716]: temporary value dropped while borrowed + --> $DIR/return_from_external_macro.rs:10:5 + | +LL | ret_from_ext::foo!() + | ^^^^^^^^^^^^^^^^^^^^ + | | + | creates a temporary value which is freed while still in use + | opaque type requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement + | + = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0515, E0716. +For more information about an error, try `rustc --explain E0515`. From 3cc172074a1ed94aa90372360688a000b47e6946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 2 May 2025 13:44:51 +0200 Subject: [PATCH 086/262] collateral damage in derive tests, improves errors by not refering to implementation details --- .../deriving-with-repr-packed-move-errors.rs | 18 ++++----- ...riving-with-repr-packed-move-errors.stderr | 39 ++++++++++--------- tests/ui/derives/deriving-with-repr-packed.rs | 2 +- .../derives/deriving-with-repr-packed.stderr | 12 +++--- .../lifetime_errors_on_promotion_misusage.rs | 4 +- ...fetime_errors_on_promotion_misusage.stderr | 16 ++++---- 6 files changed, 48 insertions(+), 43 deletions(-) diff --git a/tests/ui/derives/deriving-with-repr-packed-move-errors.rs b/tests/ui/derives/deriving-with-repr-packed-move-errors.rs index ffeb02d78b84..17aa750332c4 100644 --- a/tests/ui/derives/deriving-with-repr-packed-move-errors.rs +++ b/tests/ui/derives/deriving-with-repr-packed-move-errors.rs @@ -11,15 +11,15 @@ use std::cmp::Ordering; #[repr(packed)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] struct StructA(String); -//~^ ERROR: cannot move out of `self` which is behind a shared reference -//~| ERROR: cannot move out of `self` which is behind a shared reference -//~| ERROR: cannot move out of `other` which is behind a shared reference -//~| ERROR: cannot move out of `self` which is behind a shared reference -//~| ERROR: cannot move out of `other` which is behind a shared reference -//~| ERROR: cannot move out of `self` which is behind a shared reference -//~| ERROR: cannot move out of `other` which is behind a shared reference -//~| ERROR: cannot move out of `self` which is behind a shared reference -//~| ERROR: cannot move out of `self` which is behind a shared reference +//~^ ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] +//~| ERROR: cannot move out of a shared reference [E0507] // Unrelated impl: additinal diagnostic should NOT be emitted diff --git a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr index 68c3c8ae9ead..4b085425033d 100644 --- a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr @@ -1,10 +1,10 @@ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | ----- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable @@ -12,13 +12,13 @@ help: consider cloning the value if the performance cost is acceptable LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | --------- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable @@ -26,27 +26,28 @@ help: consider cloning the value if the performance cost is acceptable LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `other` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | --------- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider cloning the value if the performance cost is acceptable | LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | ---------- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable @@ -54,27 +55,28 @@ help: consider cloning the value if the performance cost is acceptable LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `other` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | ---------- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider cloning the value if the performance cost is acceptable | LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | --- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable @@ -82,27 +84,28 @@ help: consider cloning the value if the performance cost is acceptable LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `other` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | --- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider cloning the value if the performance cost is acceptable | LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | ---- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(Hash)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable @@ -110,13 +113,13 @@ help: consider cloning the value if the performance cost is acceptable LL | struct StructA(String.clone()); | ++++++++ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16 | LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] | ----- in this derive macro expansion LL | struct StructA(String); - | ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait + | ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait | = note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour help: consider cloning the value if the performance cost is acceptable diff --git a/tests/ui/derives/deriving-with-repr-packed.rs b/tests/ui/derives/deriving-with-repr-packed.rs index d17b52842cef..cba0413c992e 100644 --- a/tests/ui/derives/deriving-with-repr-packed.rs +++ b/tests/ui/derives/deriving-with-repr-packed.rs @@ -20,7 +20,7 @@ struct Y(usize); #[derive(Debug, Default)] #[repr(packed)] struct X(Y); -//~^ ERROR cannot move out of `self` which is behind a shared reference +//~^ ERROR cannot move out of a shared reference [E0507] #[derive(Debug)] #[repr(packed)] diff --git a/tests/ui/derives/deriving-with-repr-packed.stderr b/tests/ui/derives/deriving-with-repr-packed.stderr index 5117f8d1112c..9cfc4abdc0cb 100644 --- a/tests/ui/derives/deriving-with-repr-packed.stderr +++ b/tests/ui/derives/deriving-with-repr-packed.stderr @@ -1,11 +1,11 @@ -error[E0507]: cannot move out of `self` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed.rs:22:10 | LL | #[derive(Debug, Default)] | ----- in this derive macro expansion LL | #[repr(packed)] LL | struct X(Y); - | ^ move occurs because `self.0` has type `Y`, which does not implement the `Copy` trait + | ^ move occurs because value has type `Y`, which does not implement the `Copy` trait | note: if `Y` implemented `Clone`, you could clone the value --> $DIR/deriving-with-repr-packed.rs:16:1 @@ -23,14 +23,14 @@ error[E0161]: cannot move a value of type `[u8]` LL | data: [u8], | ^^^^^^^^^^ the size of `[u8]` cannot be statically determined -error[E0507]: cannot move out of `self.data` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed.rs:29:5 | LL | #[derive(Debug)] | ----- in this derive macro expansion ... LL | data: [u8], - | ^^^^^^^^^^ move occurs because `self.data` has type `[u8]`, which does not implement the `Copy` trait + | ^^^^^^^^^^ move occurs because value has type `[u8]`, which does not implement the `Copy` trait | = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour @@ -40,14 +40,14 @@ error[E0161]: cannot move a value of type `str` LL | data: str, | ^^^^^^^^^ the size of `str` cannot be statically determined -error[E0507]: cannot move out of `self.data` which is behind a shared reference +error[E0507]: cannot move out of a shared reference --> $DIR/deriving-with-repr-packed.rs:38:5 | LL | #[derive(Debug)] | ----- in this derive macro expansion ... LL | data: str, - | ^^^^^^^^^ move occurs because `self.data` has type `str`, which does not implement the `Copy` trait + | ^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait | = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs index e505fe435207..2771b4717fbf 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs @@ -9,14 +9,14 @@ use core::{ fn function_call_stops_borrow_extension() { let phantom_pinned = identity(pin!(PhantomPinned)); - //~^ ERROR does not live long enough + //~^ ERROR temporary value dropped while borrowed [E0716] stuff(phantom_pinned) } fn promotion_only_works_for_the_innermost_block() { let phantom_pinned = { let phantom_pinned = pin!(PhantomPinned); - //~^ ERROR does not live long enough + //~^ ERROR temporary value dropped while borrowed [E0716] phantom_pinned }; stuff(phantom_pinned) diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr index 43fb82be7c2f..4ecc6370d3ca 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr @@ -1,29 +1,31 @@ -error[E0597]: value does not live long enough +error[E0716]: temporary value dropped while borrowed --> $DIR/lifetime_errors_on_promotion_misusage.rs:11:35 | LL | let phantom_pinned = identity(pin!(PhantomPinned)); - | ^^^^^^^^^^^^^^^^^^^ - value dropped here while still borrowed + | ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | borrowed value does not live long enough + | creates a temporary value which is freed while still in use LL | LL | stuff(phantom_pinned) | -------------- borrow later used here | + = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0597]: value does not live long enough +error[E0716]: temporary value dropped while borrowed --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30 | LL | let phantom_pinned = { | -------------- borrow later stored here LL | let phantom_pinned = pin!(PhantomPinned); - | ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use ... LL | }; - | - value dropped here while still borrowed + | - temporary value is freed at the end of this statement | + = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0716`. From 5424e4f1db86d49e632d8a8e96f400e012c9153f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 2 May 2025 16:36:48 +0200 Subject: [PATCH 087/262] remove an unused codepath --- compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 0f8acadb978c..3b7d31b1b13b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2954,12 +2954,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - let name = if borrow_span.in_external_macro(self.infcx.tcx.sess.source_map()) { - // Don't name local variables in external macros. - "value".to_string() - } else { - format!("`{name}`") - }; + let name = format!("`{name}`"); let mut err = self.path_does_not_live_long_enough(borrow_span, &name); From b7c933a495a42d684f7acb493caeee3f3c4e87bf Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 2 May 2025 12:13:40 -0500 Subject: [PATCH 088/262] doc(std): fix typo lchown -> lchmod --- library/std/src/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 462c06dcea26..68e26d796537 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2994,7 +2994,7 @@ pub fn read_dir>(path: P) -> io::Result { /// When possible, permissions should be set at creation time instead. /// /// # Rationale -/// POSIX does not specify an `lchown` function, +/// POSIX does not specify an `lchmod` function, /// and symlinks can be followed regardless of what permission bits are set. /// /// # Errors From d8a52dbbf82e07b82c574bda26d7963992985491 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sat, 3 May 2025 03:00:49 +0900 Subject: [PATCH 089/262] fix: Implement mut to const ptr cast for method resolution --- .../crates/hir-ty/src/method_resolution.rs | 72 +++++++++++++++---- .../hir-ty/src/tests/method_resolution.rs | 23 ++++++ 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 8f8e26eca2ae..8e549ca0cbd5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -515,9 +515,15 @@ impl From> for VisibleFromModule { } } +#[derive(Debug, Clone)] +pub enum AutorefOrPtrAdjustment { + Autoref(Mutability), + ToConstPtr, +} + #[derive(Debug, Clone, Default)] pub struct ReceiverAdjustments { - autoref: Option, + autoref: Option, autoderefs: usize, unsize_array: bool, } @@ -535,10 +541,15 @@ impl ReceiverAdjustments { } Some((kind, new_ty)) => { ty = new_ty.clone(); + let mutbl = match self.autoref { + Some(AutorefOrPtrAdjustment::Autoref(m)) => Some(m), + Some(AutorefOrPtrAdjustment::ToConstPtr) => Some(Mutability::Not), + // FIXME should we know the mutability here, when autoref is `None`? + None => None, + }; adjust.push(Adjustment { kind: Adjust::Deref(match kind { - // FIXME should we know the mutability here, when autoref is `None`? - AutoderefKind::Overloaded => Some(OverloadedDeref(self.autoref)), + AutoderefKind::Overloaded => Some(OverloadedDeref(mutbl)), AutoderefKind::Builtin => None, }), target: new_ty, @@ -546,11 +557,27 @@ impl ReceiverAdjustments { } } } - if let Some(m) = self.autoref { + if let Some(autoref) = &self.autoref { let lt = table.new_lifetime_var(); - let a = Adjustment::borrow(m, ty, lt); - ty = a.target.clone(); - adjust.push(a); + match autoref { + AutorefOrPtrAdjustment::Autoref(m) => { + let a = Adjustment::borrow(*m, ty, lt); + ty = a.target.clone(); + adjust.push(a); + } + AutorefOrPtrAdjustment::ToConstPtr => { + if let TyKind::Raw(Mutability::Mut, pointee) = ty.kind(Interner) { + let a = Adjustment { + kind: Adjust::Pointer(PointerCast::MutToConstPointer), + target: TyKind::Raw(Mutability::Not, pointee.clone()).intern(Interner), + }; + ty = a.target.clone(); + adjust.push(a); + } else { + never!("`ToConstPtr` target is not a raw mutable pointer"); + } + } + }; } if self.unsize_array { ty = 'it: { @@ -575,8 +602,8 @@ impl ReceiverAdjustments { (ty, adjust) } - fn with_autoref(&self, m: Mutability) -> ReceiverAdjustments { - Self { autoref: Some(m), ..*self } + fn with_autoref(&self, a: AutorefOrPtrAdjustment) -> ReceiverAdjustments { + Self { autoref: Some(a), ..*self } } } @@ -1051,7 +1078,7 @@ fn iterate_method_candidates_with_autoref( let mut maybe_reborrowed = first_adjustment.clone(); if let Some((_, _, m)) = receiver_ty.value.as_reference() { // Prefer reborrow of references to move - maybe_reborrowed.autoref = Some(m); + maybe_reborrowed.autoref = Some(AutorefOrPtrAdjustment::Autoref(m)); maybe_reborrowed.autoderefs += 1; } @@ -1063,15 +1090,34 @@ fn iterate_method_candidates_with_autoref( binders: receiver_ty.binders.clone(), }; - iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?; + iterate_method_candidates_by_receiver( + refed, + first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Not)), + )?; let ref_muted = Canonical { value: TyKind::Ref(Mutability::Mut, error_lifetime(), receiver_ty.value.clone()) .intern(Interner), - binders: receiver_ty.binders, + binders: receiver_ty.binders.clone(), }; - iterate_method_candidates_by_receiver(ref_muted, first_adjustment.with_autoref(Mutability::Mut)) + iterate_method_candidates_by_receiver( + ref_muted, + first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Mut)), + )?; + + if let Some((ty, Mutability::Mut)) = receiver_ty.value.as_raw_ptr() { + let const_ptr_ty = Canonical { + value: TyKind::Raw(Mutability::Not, ty.clone()).intern(Interner), + binders: receiver_ty.binders, + }; + iterate_method_candidates_by_receiver( + const_ptr_ty, + first_adjustment.with_autoref(AutorefOrPtrAdjustment::ToConstPtr), + )?; + } + + ControlFlow::Continue(()) } pub trait MethodCandidateCallback { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs index 1f8b06fcc561..94826acca305 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs @@ -2170,3 +2170,26 @@ fn main() { "#, ); } + +#[test] +fn mut_to_const_pointer() { + check( + r#" +pub trait X { + fn perform(self) -> u64; +} + +impl X for *const u8 { + fn perform(self) -> u64 { + 42 + } +} + +fn test(x: *mut u8) { + let _v = x.perform(); + // ^ adjustments: Pointer(MutToConstPointer) + // ^^^^^^^^^^^ type: u64 +} +"#, + ); +} From 77876b5233a15e67a14ee1d22634357a3bca411f Mon Sep 17 00:00:00 2001 From: Erik Kaneda Date: Fri, 2 May 2025 11:45:09 -0700 Subject: [PATCH 090/262] zkvm: remove schmerik from maintainers list --- src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md index 09b42da26e74..1d02a7cfbc0b 100644 --- a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md @@ -8,7 +8,6 @@ RISC Zero's Zero Knowledge Virtual Machine (zkVM) implementing the RV32IM instru [@flaub](https://github.com/flaub) [@jbruestle](https://github.com/jbruestle) -[@SchmErik](https://github.com/SchmErik) ## Background From ffa7d1ee5dba9d0a9979d784a5c38e3a05a5ff9e Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 2 May 2025 16:24:28 +0000 Subject: [PATCH 091/262] borrowck nested items in dead code --- compiler/rustc_borrowck/src/lib.rs | 8 +++ compiler/rustc_borrowck/src/root_cx.rs | 5 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 10 ++-- compiler/rustc_ty_utils/src/lib.rs | 4 +- compiler/rustc_ty_utils/src/nested_bodies.rs | 34 ++++++++++++ .../rustc_ty_utils/src/stalled_generators.rs | 54 ------------------- compiler/rustc_type_ir/src/infer_ctxt.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 2 +- tests/ui/nll/nested-bodies-in-dead-code.rs | 28 ++++++++++ .../ui/nll/nested-bodies-in-dead-code.stderr | 50 +++++++++++++++++ 11 files changed, 135 insertions(+), 64 deletions(-) create mode 100644 compiler/rustc_ty_utils/src/nested_bodies.rs delete mode 100644 compiler/rustc_ty_utils/src/stalled_generators.rs create mode 100644 tests/ui/nll/nested-bodies-in-dead-code.rs create mode 100644 tests/ui/nll/nested-bodies-in-dead-code.stderr diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 44af1b765399..f9d8d858f16c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -127,6 +127,14 @@ fn mir_borrowck( Ok(tcx.arena.alloc(opaque_types)) } else { let mut root_cx = BorrowCheckRootCtxt::new(tcx, def); + // We need to manually borrowck all nested bodies from the HIR as + // we do not generate MIR for dead code. Not doing so causes us to + // never check closures in dead code. + let nested_bodies = tcx.nested_bodies_within(def); + for def_id in nested_bodies { + root_cx.get_or_insert_nested(def_id); + } + let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } = do_mir_borrowck(&mut root_cx, def, None).0; debug_assert!(closure_requirements.is_none()); diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index 13daa5c72214..66b526fa02a5 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -62,7 +62,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self.tainted_by_errors = Some(guar); } - fn get_or_insert_nested(&mut self, def_id: LocalDefId) -> &PropagatedBorrowCheckResults<'tcx> { + pub(super) fn get_or_insert_nested( + &mut self, + def_id: LocalDefId, + ) -> &PropagatedBorrowCheckResults<'tcx> { debug_assert_eq!( self.tcx.typeck_root_def_id(def_id.to_def_id()), self.root_def_id.to_def_id() diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 88f4c4ae4d36..2702aea96b54 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -387,7 +387,7 @@ rustc_queries! { } } - query stalled_generators_within( + query nested_bodies_within( key: LocalDefId ) -> &'tcx ty::List { desc { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3ea285d3d8eb..071cbe83e5db 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -684,15 +684,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.opaque_types_defined_by(defining_anchor) } - fn opaque_types_and_generators_defined_by( + fn opaque_types_and_coroutines_defined_by( self, defining_anchor: Self::LocalDefId, ) -> Self::LocalDefIds { if self.next_trait_solver_globally() { + let coroutines_defined_by = self + .nested_bodies_within(defining_anchor) + .iter() + .filter(|def_id| self.is_coroutine(def_id.to_def_id())); self.mk_local_def_ids_from_iter( - self.opaque_types_defined_by(defining_anchor) - .iter() - .chain(self.stalled_generators_within(defining_anchor)), + self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by), ) } else { self.opaque_types_defined_by(defining_anchor) diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index ea0f6b8dfba7..f79b6d44bfdf 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -29,10 +29,10 @@ mod implied_bounds; mod instance; mod layout; mod needs_drop; +mod nested_bodies; mod opaque_types; mod representability; pub mod sig_types; -mod stalled_generators; mod structural_match; mod ty; @@ -51,5 +51,5 @@ pub fn provide(providers: &mut Providers) { ty::provide(providers); instance::provide(providers); structural_match::provide(providers); - stalled_generators::provide(providers); + nested_bodies::provide(providers); } diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs new file mode 100644 index 000000000000..7c74d8eb6351 --- /dev/null +++ b/compiler/rustc_ty_utils/src/nested_bodies.rs @@ -0,0 +1,34 @@ +use rustc_hir as hir; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::Visitor; +use rustc_middle::query::Providers; +use rustc_middle::ty::{self, TyCtxt}; + +fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List { + let body = tcx.hir_body_owned_by(item); + let mut collector = + NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] }; + collector.visit_body(body); + tcx.mk_local_def_ids(&collector.nested_bodies) +} + +struct NestedBodiesVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + root_def_id: DefId, + nested_bodies: Vec, +} + +impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> { + fn visit_nested_body(&mut self, id: hir::BodyId) { + let body_def_id = self.tcx.hir_body_owner_def_id(id); + if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id { + self.nested_bodies.push(body_def_id); + let body = self.tcx.hir_body(id); + self.visit_body(body); + } + } +} + +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { nested_bodies_within, ..*providers }; +} diff --git a/compiler/rustc_ty_utils/src/stalled_generators.rs b/compiler/rustc_ty_utils/src/stalled_generators.rs deleted file mode 100644 index 8b45e8b0f6f9..000000000000 --- a/compiler/rustc_ty_utils/src/stalled_generators.rs +++ /dev/null @@ -1,54 +0,0 @@ -use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit; -use rustc_hir::intravisit::Visitor; -use rustc_middle::query::Providers; -use rustc_middle::ty::{self, TyCtxt}; - -fn stalled_generators_within<'tcx>( - tcx: TyCtxt<'tcx>, - item: LocalDefId, -) -> &'tcx ty::List { - if !tcx.next_trait_solver_globally() { - return ty::List::empty(); - } - - let body = tcx.hir_body_owned_by(item); - let mut collector = - StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] }; - collector.visit_body(body); - tcx.mk_local_def_ids(&collector.stalled_coroutines) -} - -struct StalledGeneratorVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - root_def_id: DefId, - stalled_coroutines: Vec, -} - -impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> { - fn visit_nested_body(&mut self, id: hir::BodyId) { - if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id()) - == self.root_def_id - { - let body = self.tcx.hir_body(id); - self.visit_body(body); - } - } - - fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Closure(&hir::Closure { - def_id, - kind: hir::ClosureKind::Coroutine(_), - .. - }) = ex.kind - { - self.stalled_coroutines.push(def_id); - } - intravisit::walk_expr(self, ex); - } -} - -pub(super) fn provide(providers: &mut Providers) { - *providers = Providers { stalled_generators_within, ..*providers }; -} diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 8fa56c359996..7d2654de4409 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -100,7 +100,7 @@ impl TypingMode { pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode { TypingMode::Analysis { defining_opaque_types_and_generators: cx - .opaque_types_and_generators_defined_by(body_def_id), + .opaque_types_and_coroutines_defined_by(body_def_id), } } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6410da1f7409..0fd2d9f3ad38 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -341,7 +341,7 @@ pub trait Interner: fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds; - fn opaque_types_and_generators_defined_by( + fn opaque_types_and_coroutines_defined_by( self, defining_anchor: Self::LocalDefId, ) -> Self::LocalDefIds; diff --git a/tests/ui/nll/nested-bodies-in-dead-code.rs b/tests/ui/nll/nested-bodies-in-dead-code.rs new file mode 100644 index 000000000000..6ac68f5adbce --- /dev/null +++ b/tests/ui/nll/nested-bodies-in-dead-code.rs @@ -0,0 +1,28 @@ +//@ edition: 2024 + +// Regression test for #140583. We want to borrowck nested +// bodies even if they are in dead code. While not necessary for +// soundness, it is desirable to error in such cases. + +fn main() { + return; + |x: &str| -> &'static str { x }; + //~^ ERROR lifetime may not live long enough + || { + || { + let temp = 1; + let p: &'static u32 = &temp; + //~^ ERROR `temp` does not live long enough + }; + }; + const { + let temp = 1; + let p: &'static u32 = &temp; + //~^ ERROR `temp` does not live long enough + }; + async { + let temp = 1; + let p: &'static u32 = &temp; + //~^ ERROR `temp` does not live long enough + }; +} diff --git a/tests/ui/nll/nested-bodies-in-dead-code.stderr b/tests/ui/nll/nested-bodies-in-dead-code.stderr new file mode 100644 index 000000000000..da6ccff5777c --- /dev/null +++ b/tests/ui/nll/nested-bodies-in-dead-code.stderr @@ -0,0 +1,50 @@ +error: lifetime may not live long enough + --> $DIR/nested-bodies-in-dead-code.rs:9:33 + | +LL | |x: &str| -> &'static str { x }; + | - ^ returning this value requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` + +error[E0597]: `temp` does not live long enough + --> $DIR/nested-bodies-in-dead-code.rs:14:35 + | +LL | let temp = 1; + | ---- binding `temp` declared here +LL | let p: &'static u32 = &temp; + | ------------ ^^^^^ borrowed value does not live long enough + | | + | type annotation requires that `temp` is borrowed for `'static` +LL | +LL | }; + | - `temp` dropped here while still borrowed + +error[E0597]: `temp` does not live long enough + --> $DIR/nested-bodies-in-dead-code.rs:20:31 + | +LL | let temp = 1; + | ---- binding `temp` declared here +LL | let p: &'static u32 = &temp; + | ------------ ^^^^^ borrowed value does not live long enough + | | + | type annotation requires that `temp` is borrowed for `'static` +LL | +LL | }; + | - `temp` dropped here while still borrowed + +error[E0597]: `temp` does not live long enough + --> $DIR/nested-bodies-in-dead-code.rs:25:31 + | +LL | let temp = 1; + | ---- binding `temp` declared here +LL | let p: &'static u32 = &temp; + | ------------ ^^^^^ borrowed value does not live long enough + | | + | type annotation requires that `temp` is borrowed for `'static` +LL | +LL | }; + | - `temp` dropped here while still borrowed + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. From dcee18b3b8cd23e6cd3ed20805d97515526852f7 Mon Sep 17 00:00:00 2001 From: moxian Date: Thu, 1 May 2025 14:34:04 -0700 Subject: [PATCH 092/262] Add a regression test for #140545 --- .../double-wrap-with-defining-use.rs | 12 ++++++++++++ .../double-wrap-with-defining-use.stderr | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs create mode 100644 tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs new file mode 100644 index 000000000000..339277fec37e --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs @@ -0,0 +1,12 @@ +// Regression test for ICE from issue #140545 +// The error message is confusing and wrong, but that's a different problem (#139350) +//@ edition:2018 + +trait Foo {} +fn a(x: impl Foo) -> impl Foo { + if true { x } else { a(a(x)) } + //~^ ERROR: expected generic type parameter, found `impl Foo` [E0792] + //~| ERROR: type parameter `impl Foo` is part of concrete type but not used in parameter list for the `impl Trait` type alias +} + +fn main(){} diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr new file mode 100644 index 000000000000..1b02811e31b7 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr @@ -0,0 +1,17 @@ +error[E0792]: expected generic type parameter, found `impl Foo` + --> $DIR/double-wrap-with-defining-use.rs:7:26 + | +LL | fn a(x: impl Foo) -> impl Foo { + | -------- this generic parameter must be used with a generic type parameter +LL | if true { x } else { a(a(x)) } + | ^^^^^^^ + +error: type parameter `impl Foo` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/double-wrap-with-defining-use.rs:7:26 + | +LL | if true { x } else { a(a(x)) } + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0792`. From 4671081bdbc73d35a465a150937b6d0ecd26087f Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Fri, 2 May 2025 22:08:35 +0200 Subject: [PATCH 093/262] Refactor rustc_on_unimplemented's filter parser --- Cargo.lock | 1 - compiler/rustc_trait_selection/Cargo.toml | 1 - compiler/rustc_trait_selection/messages.ftl | 26 +- .../traits/on_unimplemented.rs | 52 ++- .../traits/on_unimplemented_condition.rs | 321 ++++++++++++++---- compiler/rustc_trait_selection/src/errors.rs | 56 ++- tests/ui/on-unimplemented/bad-annotation.rs | 64 +++- .../ui/on-unimplemented/bad-annotation.stderr | 110 +++--- 8 files changed, 457 insertions(+), 174 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97a90a44a398..a5b41b6edd5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4520,7 +4520,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 1c61e23362a8..e6de2a3978d1 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 74e38f525c8e..cf6dd40718b3 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -148,9 +148,6 @@ trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement -trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]` - .label = empty on-clause here - trait_selection_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}` trait_selection_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type @@ -187,9 +184,6 @@ trait_selection_inherent_projection_normalization_overflow = overflow evaluating trait_selection_invalid_format_specifier = invalid format specifier .help = no format specifier are supported in this position -trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]` - .label = invalid on-clause here - trait_selection_label_bad = {$bad_kind -> *[other] cannot infer type [more_info] cannot infer {$prefix_kind -> @@ -237,10 +231,6 @@ trait_selection_negative_positive_conflict = found both positive and negative im .positive_implementation_here = positive implementation here .positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}` -trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value - .label = expected value here - .note = eg `#[rustc_on_unimplemented(message="foo")]` - trait_selection_nothing = {""} trait_selection_oc_cant_coerce_force_inline = @@ -339,6 +329,22 @@ trait_selection_ril_introduced_by = requirement introduced by this return type trait_selection_ril_introduced_here = `'static` requirement introduced here trait_selection_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type +trait_selection_rustc_on_unimplemented_empty_on_clause = empty `on`-clause in `#[rustc_on_unimplemented]` + .label = empty `on`-clause here +trait_selection_rustc_on_unimplemented_expected_identifier = expected an identifier inside this `on`-clause + .label = expected an identifier here, not `{$path}` +trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not = expected a single predicate in `not(..)` + .label = unexpected quantity of predicates here +trait_selection_rustc_on_unimplemented_invalid_flag = invalid flag in `on`-clause + .label = expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `{$invalid_flag}` +trait_selection_rustc_on_unimplemented_invalid_predicate = this predicate is invalid + .label = expected one of `any`, `all` or `not` here, not `{$invalid_pred}` +trait_selection_rustc_on_unimplemented_missing_value = this attribute must have a value + .label = expected value here + .note = e.g. `#[rustc_on_unimplemented(message="foo")]` +trait_selection_rustc_on_unimplemented_unsupported_literal_in_on = literals inside `on`-clauses are not supported + .label = unexpected literal here + trait_selection_source_kind_closure_return = try giving this closure an explicit return type diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 4c4491269b75..d5ee6e2123a1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; +use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{AttrArgs, Attribute}; use rustc_macros::LintDiagnostic; @@ -13,17 +14,16 @@ use rustc_middle::ty::{self, GenericArgsRef, GenericParamDef, GenericParamDefKin use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::{Span, Symbol, sym}; use tracing::{debug, info}; -use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::{ObligationCauseCode, PredicateObligation}; use crate::error_reporting::TypeErrCtxt; -use crate::error_reporting::traits::on_unimplemented_condition::{Condition, ConditionOptions}; +use crate::error_reporting::traits::on_unimplemented_condition::{ + ConditionOptions, OnUnimplementedCondition, +}; use crate::error_reporting::traits::on_unimplemented_format::{ Ctx, FormatArgs, FormatString, FormatWarning, }; -use crate::errors::{ - EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, -}; +use crate::errors::{InvalidOnClause, NoValueInOnUnimplemented}; use crate::infer::InferCtxtExt; impl<'tcx> TypeErrCtxt<'_, 'tcx> { @@ -306,21 +306,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString { /// Symbol of the format string, i.e. `"content"` - pub symbol: Symbol, + symbol: Symbol, ///The span of the format string, i.e. `"content"` - pub span: Span, - pub is_diagnostic_namespace_variant: bool, + span: Span, + is_diagnostic_namespace_variant: bool, } #[derive(Debug)] pub struct OnUnimplementedDirective { - pub condition: Option, - pub subcommands: Vec, - pub message: Option<(Span, OnUnimplementedFormatString)>, - pub label: Option<(Span, OnUnimplementedFormatString)>, - pub notes: Vec, - pub parent_label: Option, - pub append_const_msg: Option, + condition: Option, + subcommands: Vec, + message: Option<(Span, OnUnimplementedFormatString)>, + label: Option<(Span, OnUnimplementedFormatString)>, + notes: Vec, + parent_label: Option, + append_const_msg: Option, } /// For the `#[rustc_on_unimplemented]` attribute @@ -427,18 +427,12 @@ impl<'tcx> OnUnimplementedDirective { } else { let cond = item_iter .next() - .ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))? - .meta_item_or_bool() - .ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?; - attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| { - if let Some(value) = cfg.value - && let Err(guar) = parse_value(value, cfg.span) - { - errored = Some(guar); - } - true - }); - Some(Condition { inner: cond.clone() }) + .ok_or_else(|| tcx.dcx().emit_err(InvalidOnClause::Empty { span }))?; + + match OnUnimplementedCondition::parse(cond) { + Ok(condition) => Some(condition), + Err(e) => return Err(tcx.dcx().emit_err(e)), + } }; let mut message = None; @@ -724,7 +718,7 @@ impl<'tcx> OnUnimplementedDirective { result } - pub fn evaluate( + pub(crate) fn evaluate( &self, tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, @@ -744,7 +738,7 @@ impl<'tcx> OnUnimplementedDirective { for command in self.subcommands.iter().chain(Some(self)).rev() { debug!(?command); if let Some(ref condition) = command.condition - && !condition.matches_predicate(tcx, condition_options) + && !condition.matches_predicate(condition_options) { debug!("evaluate: skipping {:?} due to condition", command); continue; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs index 116cfb01cb63..13753761f092 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs @@ -1,52 +1,251 @@ -use rustc_ast::MetaItemInner; -use rustc_attr_parsing as attr; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_ast::{MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; -use rustc_span::{DesugaringKind, Span, Symbol, kw, sym}; +use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym}; -/// A predicate in an attribute using on, all, any, -/// similar to a cfg predicate. +use crate::errors::InvalidOnClause; + +/// Represents the `on` filter in `#[rustc_on_unimplemented]`. #[derive(Debug)] -pub struct Condition { - pub inner: MetaItemInner, +pub(crate) struct OnUnimplementedCondition { + span: Span, + pred: Predicate, } -impl Condition { - pub fn span(&self) -> Span { - self.inner.span() +impl OnUnimplementedCondition { + pub(crate) fn span(&self) -> Span { + self.span } - pub fn matches_predicate<'tcx>(&self, tcx: TyCtxt<'tcx>, options: &ConditionOptions) -> bool { - attr::eval_condition(&self.inner, tcx.sess, Some(tcx.features()), &mut |cfg| { - let value = cfg.value.map(|v| { - // `with_no_visible_paths` is also used when generating the options, - // so we need to match it here. - ty::print::with_no_visible_paths!({ - Parser::new(v.as_str(), None, None, false, ParseMode::Format) - .map(|p| match p { - Piece::Lit(s) => s.to_owned(), - Piece::NextArgument(a) => match a.position { - Position::ArgumentNamed(arg) => { - let s = Symbol::intern(arg); - match options.generic_args.iter().find(|(k, _)| *k == s) { - Some((_, val)) => val.to_string(), - None => format!("{{{arg}}}"), - } - } - Position::ArgumentImplicitlyIs(_) => String::from("{}"), - Position::ArgumentIs(idx) => format!("{{{idx}}}"), - }, - }) - .collect() - }) - }); - - options.contains(cfg.name, &value) + pub(crate) fn matches_predicate(&self, options: &ConditionOptions) -> bool { + self.pred.eval(&mut |p| match p { + FlagOrNv::Flag(b) => options.has_flag(*b), + FlagOrNv::NameValue(NameValue { name, value }) => { + let value = value.format(&options.generic_args); + options.contains(*name, value) + } }) } + + pub(crate) fn parse(input: &MetaItemInner) -> Result { + let span = input.span(); + let pred = Predicate::parse(input)?; + Ok(OnUnimplementedCondition { span, pred }) + } } -/// Used with `Condition::matches_predicate` to test whether the condition applies +/// Predicate(s) in `#[rustc_on_unimplemented]`'s `on` filter. See [`OnUnimplementedCondition`]. +/// +/// It is similar to the predicate in the `cfg` attribute, +/// and may contain nested predicates. +#[derive(Debug)] +enum Predicate { + /// A condition like `on(crate_local)`. + Flag(Flag), + /// A match, like `on(Rhs = "Whatever")`. + Match(NameValue), + /// Negation, like `on(not($pred))`. + Not(Box), + /// True if all predicates are true, like `on(all($a, $b, $c))`. + All(Vec), + /// True if any predicate is true, like `on(any($a, $b, $c))`. + Any(Vec), +} + +impl Predicate { + fn parse(input: &MetaItemInner) -> Result { + let meta_item = match input { + MetaItemInner::MetaItem(meta_item) => meta_item, + MetaItemInner::Lit(lit) => { + return Err(InvalidOnClause::UnsupportedLiteral { span: lit.span }); + } + }; + + let Some(predicate) = meta_item.ident() else { + return Err(InvalidOnClause::ExpectedIdentifier { + span: meta_item.path.span, + path: meta_item.path.clone(), + }); + }; + + match meta_item.kind { + MetaItemKind::List(ref mis) => match predicate.name { + sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis)?)), + sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis)?)), + sym::not => match &**mis { + [one] => Ok(Predicate::Not(Box::new(Predicate::parse(one)?))), + [first, .., last] => Err(InvalidOnClause::ExpectedOnePredInNot { + span: first.span().to(last.span()), + }), + [] => Err(InvalidOnClause::ExpectedOnePredInNot { span: meta_item.span }), + }, + invalid_pred => { + Err(InvalidOnClause::InvalidPredicate { span: predicate.span, invalid_pred }) + } + }, + MetaItemKind::NameValue(MetaItemLit { symbol, .. }) => { + let name = Name::parse(predicate); + let value = FilterFormatString::parse(symbol); + let kv = NameValue { name, value }; + Ok(Predicate::Match(kv)) + } + MetaItemKind::Word => { + let flag = Flag::parse(predicate)?; + Ok(Predicate::Flag(flag)) + } + } + } + + fn parse_sequence(sequence: &[MetaItemInner]) -> Result, InvalidOnClause> { + sequence.iter().map(Predicate::parse).collect() + } + + fn eval(&self, eval: &mut impl FnMut(FlagOrNv<'_>) -> bool) -> bool { + match self { + Predicate::Flag(flag) => eval(FlagOrNv::Flag(flag)), + Predicate::Match(nv) => eval(FlagOrNv::NameValue(nv)), + Predicate::Not(not) => !not.eval(eval), + Predicate::All(preds) => preds.into_iter().all(|pred| pred.eval(eval)), + Predicate::Any(preds) => preds.into_iter().any(|pred| pred.eval(eval)), + } + } +} + +/// Represents a `MetaWord` in an `on`-filter. +#[derive(Debug, Clone, Copy)] +enum Flag { + /// Whether the code causing the trait bound to not be fulfilled + /// is part of the user's crate. + CrateLocal, + /// Whether the obligation is user-specified rather than derived. + Direct, + /// Whether we are in some kind of desugaring like + /// `?` or `try { .. }`. + FromDesugaring, +} + +impl Flag { + fn parse(Ident { name, span }: Ident) -> Result { + match name { + sym::crate_local => Ok(Flag::CrateLocal), + sym::direct => Ok(Flag::Direct), + sym::from_desugaring => Ok(Flag::FromDesugaring), + invalid_flag => Err(InvalidOnClause::InvalidFlag { invalid_flag, span }), + } + } +} + +/// A `MetaNameValueStr` in an `on`-filter. +/// +/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`. +#[derive(Debug, Clone)] +struct NameValue { + name: Name, + /// Something like `"&str"` or `"alloc::string::String"`, + /// in which case it just contains a single string piece. + /// But if it is something like `"&[{A}]"` then it must be formatted later. + value: FilterFormatString, +} + +/// The valid names of the `on` filter. +#[derive(Debug, Clone, Copy)] +enum Name { + Cause, + FromDesugaring, + SelfUpper, + GenericArg(Symbol), +} + +impl Name { + fn parse(Ident { name, .. }: Ident) -> Self { + match name { + sym::_Self | kw::SelfUpper => Name::SelfUpper, + sym::from_desugaring => Name::FromDesugaring, + sym::cause => Name::Cause, + // FIXME(mejrs) Perhaps we should start checking that + // this actually is a valid generic parameter? + generic => Name::GenericArg(generic), + } + } +} + +#[derive(Debug, Clone)] +enum FlagOrNv<'p> { + Flag(&'p Flag), + NameValue(&'p NameValue), +} + +/// Represents a value inside an `on` filter. +/// +/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`. +/// If it is a simple literal like this then `pieces` will be `[LitOrArg::Lit("value")]`. +/// The `Arg` variant is used when it contains formatting like +/// `#[rustc_on_unimplemented(on(Self = "&[{A}]", message = "hello"))]`. +#[derive(Debug, Clone)] +struct FilterFormatString { + pieces: Vec, +} + +#[derive(Debug, Clone)] +enum LitOrArg { + Lit(String), + Arg(String), +} + +impl FilterFormatString { + fn parse(input: Symbol) -> Self { + let pieces = Parser::new(input.as_str(), None, None, false, ParseMode::Format) + .map(|p| match p { + Piece::Lit(s) => LitOrArg::Lit(s.to_owned()), + // We just ignore formatspecs here + Piece::NextArgument(a) => match a.position { + // In `TypeErrCtxt::on_unimplemented_note` we substitute `"{integral}"` even + // if the integer type has been resolved, to allow targeting all integers. + // `"{integer}"` and `"{float}"` come from numerics that haven't been inferred yet, + // from the `Display` impl of `InferTy` to be precise. + // + // Don't try to format these later! + Position::ArgumentNamed(arg @ "integer" | arg @ "integral" | arg @ "float") => { + LitOrArg::Lit(format!("{{{arg}}}")) + } + + // FIXME(mejrs) We should check if these correspond to a generic of the trait. + Position::ArgumentNamed(arg) => LitOrArg::Arg(arg.to_owned()), + + // FIXME(mejrs) These should really be warnings/errors + Position::ArgumentImplicitlyIs(_) => LitOrArg::Lit(String::from("{}")), + Position::ArgumentIs(idx) => LitOrArg::Lit(format!("{{{idx}}}")), + }, + }) + .collect(); + Self { pieces } + } + + fn format(&self, generic_args: &[(Symbol, String)]) -> String { + let mut ret = String::new(); + + for piece in &self.pieces { + match piece { + LitOrArg::Lit(s) => ret.push_str(s), + LitOrArg::Arg(arg) => { + let s = Symbol::intern(arg); + match generic_args.iter().find(|(k, _)| *k == s) { + Some((_, val)) => ret.push_str(val), + None => { + // FIXME(mejrs) If we start checking as mentioned in + // FilterFormatString::parse then this shouldn't happen + let _ = std::fmt::write(&mut ret, format_args!("{{{s}}}")); + } + } + } + } + } + + ret + } +} + +/// Used with `OnUnimplementedCondition::matches_predicate` to evaluate the +/// [`OnUnimplementedCondition`]. /// /// For example, given a /// ```rust,ignore (just an example) @@ -85,36 +284,34 @@ impl Condition { /// } /// ``` #[derive(Debug)] -pub struct ConditionOptions { +pub(crate) struct ConditionOptions { /// All the self types that may apply. - /// for example - pub self_types: Vec, + pub(crate) self_types: Vec, // The kind of compiler desugaring. - pub from_desugaring: Option, - /// Match on a variant of [rustc_infer::traits::ObligationCauseCode] - pub cause: Option, - pub crate_local: bool, + pub(crate) from_desugaring: Option, + /// Match on a variant of [rustc_infer::traits::ObligationCauseCode]. + pub(crate) cause: Option, + pub(crate) crate_local: bool, /// Is the obligation "directly" user-specified, rather than derived? - pub direct: bool, - // A list of the generic arguments and their reified types - pub generic_args: Vec<(Symbol, String)>, + pub(crate) direct: bool, + // A list of the generic arguments and their reified types. + pub(crate) generic_args: Vec<(Symbol, String)>, } impl ConditionOptions { - pub fn contains(&self, key: Symbol, value: &Option) -> bool { - match (key, value) { - (sym::_Self | kw::SelfUpper, Some(value)) => self.self_types.contains(&value), - // from_desugaring as a flag - (sym::from_desugaring, None) => self.from_desugaring.is_some(), - // from_desugaring as key == value - (sym::from_desugaring, Some(v)) if let Some(ds) = self.from_desugaring => ds.matches(v), - (sym::cause, Some(value)) => self.cause.as_deref() == Some(value), - (sym::crate_local, None) => self.crate_local, - (sym::direct, None) => self.direct, - (other, Some(value)) => { - self.generic_args.iter().any(|(k, v)| *k == other && v == value) - } - _ => false, + fn has_flag(&self, name: Flag) -> bool { + match name { + Flag::CrateLocal => self.crate_local, + Flag::Direct => self.direct, + Flag::FromDesugaring => self.from_desugaring.is_some(), + } + } + fn contains(&self, name: Name, value: String) -> bool { + match name { + Name::SelfUpper => self.self_types.contains(&value), + Name::FromDesugaring => self.from_desugaring.is_some_and(|ds| ds.matches(&value)), + Name::Cause => self.cause == Some(value), + Name::GenericArg(arg) => self.generic_args.contains(&(arg, value)), } } } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 756d9a57b935..21d053124810 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +use rustc_ast::Path; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ @@ -31,23 +32,50 @@ pub struct UnableToConstructConstantValue<'a> { } #[derive(Diagnostic)] -#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = E0232)] -pub struct EmptyOnClauseInOnUnimplemented { - #[primary_span] - #[label] - pub span: Span, +pub enum InvalidOnClause { + #[diag(trait_selection_rustc_on_unimplemented_empty_on_clause, code = E0232)] + Empty { + #[primary_span] + #[label] + span: Span, + }, + #[diag(trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not, code = E0232)] + ExpectedOnePredInNot { + #[primary_span] + #[label] + span: Span, + }, + #[diag(trait_selection_rustc_on_unimplemented_unsupported_literal_in_on, code = E0232)] + UnsupportedLiteral { + #[primary_span] + #[label] + span: Span, + }, + #[diag(trait_selection_rustc_on_unimplemented_expected_identifier, code = E0232)] + ExpectedIdentifier { + #[primary_span] + #[label] + span: Span, + path: Path, + }, + #[diag(trait_selection_rustc_on_unimplemented_invalid_predicate, code = E0232)] + InvalidPredicate { + #[primary_span] + #[label] + span: Span, + invalid_pred: Symbol, + }, + #[diag(trait_selection_rustc_on_unimplemented_invalid_flag, code = E0232)] + InvalidFlag { + #[primary_span] + #[label] + span: Span, + invalid_flag: Symbol, + }, } #[derive(Diagnostic)] -#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = E0232)] -pub struct InvalidOnClauseInOnUnimplemented { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = E0232)] +#[diag(trait_selection_rustc_on_unimplemented_missing_value, code = E0232)] #[note] pub struct NoValueInOnUnimplemented { #[primary_span] diff --git a/tests/ui/on-unimplemented/bad-annotation.rs b/tests/ui/on-unimplemented/bad-annotation.rs index 32b825ee3cc2..25de59781102 100644 --- a/tests/ui/on-unimplemented/bad-annotation.rs +++ b/tests/ui/on-unimplemented/bad-annotation.rs @@ -25,49 +25,85 @@ trait ParameterNotPresent {} trait NoPositionalArgs {} #[rustc_on_unimplemented(lorem = "")] -//~^ ERROR this attribute must have a valid +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here trait EmptyMessage {} #[rustc_on_unimplemented(lorem(ipsum(dolor)))] -//~^ ERROR this attribute must have a valid +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here trait Invalid {} #[rustc_on_unimplemented(message = "x", message = "y")] -//~^ ERROR this attribute must have a valid +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here trait DuplicateMessage {} #[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))] -//~^ ERROR this attribute must have a valid +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here trait OnInWrongPosition {} #[rustc_on_unimplemented(on(), message = "y")] //~^ ERROR empty `on`-clause -trait NoEmptyOn {} +//~^^ NOTE empty `on`-clause here +trait EmptyOn {} #[rustc_on_unimplemented(on = "x", message = "y")] -//~^ ERROR this attribute must have a valid +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here trait ExpectedPredicateInOn {} #[rustc_on_unimplemented(on(x = "y"), message = "y")] trait OnWithoutDirectives {} -#[rustc_on_unimplemented(on(desugared, on(desugared, message = "x")), message = "y")] -//~^ ERROR this attribute must have a valid -trait NoNestedOn {} +#[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")] +//~^ ERROR this attribute must have a value +//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]` +//~^^^ NOTE expected value here +trait NestedOn {} -// caught by `OnUnimplementedDirective::parse`, *not* `eval_condition` #[rustc_on_unimplemented(on("y", message = "y"))] -//~^ ERROR invalid `on`-clause +//~^ ERROR literals inside `on`-clauses are not supported +//~^^ NOTE unexpected literal here trait UnsupportedLiteral {} +#[rustc_on_unimplemented(on(42, message = "y"))] +//~^ ERROR literals inside `on`-clauses are not supported +//~^^ NOTE unexpected literal here +trait UnsupportedLiteral2 {} + #[rustc_on_unimplemented(on(not(a, b), message = "y"))] -//~^ ERROR expected 1 cfg-pattern +//~^ ERROR expected a single predicate in `not(..)` [E0232] +//~^^ NOTE unexpected quantity of predicates here trait ExpectedOnePattern {} +#[rustc_on_unimplemented(on(not(), message = "y"))] +//~^ ERROR expected a single predicate in `not(..)` [E0232] +//~^^ NOTE unexpected quantity of predicates here +trait ExpectedOnePattern2 {} + #[rustc_on_unimplemented(on(thing::What, message = "y"))] -//~^ ERROR `cfg` predicate key must be an identifier +//~^ ERROR expected an identifier inside this `on`-clause +//~^^ NOTE expected an identifier here, not `thing::What` trait KeyMustBeIdentifier {} #[rustc_on_unimplemented(on(thing::What = "value", message = "y"))] -//~^ ERROR `cfg` predicate key must be an identifier +//~^ ERROR expected an identifier inside this `on`-clause +//~^^ NOTE expected an identifier here, not `thing::What` trait KeyMustBeIdentifier2 {} + +#[rustc_on_unimplemented(on(aaaaaaaaaaaaaa(a, b), message = "y"))] +//~^ ERROR this predicate is invalid +//~^^ NOTE expected one of `any`, `all` or `not` here, not `aaaaaaaaaaaaaa` +trait InvalidPredicate {} + +#[rustc_on_unimplemented(on(something, message = "y"))] +//~^ ERROR invalid flag in `on`-clause +//~^^ NOTE expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something` +trait InvalidFlag {} diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index 817d3c42cf69..35b919c7b785 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -23,85 +23,109 @@ error[E0231]: positional format arguments are not allowed here LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] | ^ -error[E0232]: this attribute must have a valid value +error[E0232]: this attribute must have a value --> $DIR/bad-annotation.rs:27:26 | LL | #[rustc_on_unimplemented(lorem = "")] | ^^^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` -error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:31:26 +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:33:26 | LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] | ^^^^^^^^^^^^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` -error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:35:41 +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:39:41 | LL | #[rustc_on_unimplemented(message = "x", message = "y")] | ^^^^^^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` -error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:39:41 +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:45:41 | LL | #[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]` - --> $DIR/bad-annotation.rs:43:26 + --> $DIR/bad-annotation.rs:51:26 | LL | #[rustc_on_unimplemented(on(), message = "y")] - | ^^^^ empty on-clause here + | ^^^^ empty `on`-clause here -error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:47:26 +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:56:26 | LL | #[rustc_on_unimplemented(on = "x", message = "y")] | ^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` -error[E0232]: this attribute must have a valid value - --> $DIR/bad-annotation.rs:54:40 +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:65:46 | -LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message = "x")), message = "y")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here +LL | #[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here | - = note: eg `#[rustc_on_unimplemented(message="foo")]` + = note: e.g. `#[rustc_on_unimplemented(message="foo")]` -error[E0232]: invalid `on`-clause in `#[rustc_on_unimplemented]` - --> $DIR/bad-annotation.rs:59:26 - | -LL | #[rustc_on_unimplemented(on("y", message = "y"))] - | ^^^^^^^^^^^^^^^^^^^^^^ invalid on-clause here - -error[E0536]: expected 1 cfg-pattern - --> $DIR/bad-annotation.rs:63:29 - | -LL | #[rustc_on_unimplemented(on(not(a, b), message = "y"))] - | ^^^^^^^^^ - -error: `cfg` predicate key must be an identifier - --> $DIR/bad-annotation.rs:67:29 - | -LL | #[rustc_on_unimplemented(on(thing::What, message = "y"))] - | ^^^^^^^^^^^ - -error: `cfg` predicate key must be an identifier +error[E0232]: literals inside `on`-clauses are not supported --> $DIR/bad-annotation.rs:71:29 | +LL | #[rustc_on_unimplemented(on("y", message = "y"))] + | ^^^ unexpected literal here + +error[E0232]: literals inside `on`-clauses are not supported + --> $DIR/bad-annotation.rs:76:29 + | +LL | #[rustc_on_unimplemented(on(42, message = "y"))] + | ^^ unexpected literal here + +error[E0232]: expected a single predicate in `not(..)` + --> $DIR/bad-annotation.rs:81:33 + | +LL | #[rustc_on_unimplemented(on(not(a, b), message = "y"))] + | ^^^^ unexpected quantity of predicates here + +error[E0232]: expected a single predicate in `not(..)` + --> $DIR/bad-annotation.rs:86:29 + | +LL | #[rustc_on_unimplemented(on(not(), message = "y"))] + | ^^^^^ unexpected quantity of predicates here + +error[E0232]: expected an identifier inside this `on`-clause + --> $DIR/bad-annotation.rs:91:29 + | +LL | #[rustc_on_unimplemented(on(thing::What, message = "y"))] + | ^^^^^^^^^^^ expected an identifier here, not `thing::What` + +error[E0232]: expected an identifier inside this `on`-clause + --> $DIR/bad-annotation.rs:96:29 + | LL | #[rustc_on_unimplemented(on(thing::What = "value", message = "y"))] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ expected an identifier here, not `thing::What` -error: aborting due to 14 previous errors +error[E0232]: this predicate is invalid + --> $DIR/bad-annotation.rs:101:29 + | +LL | #[rustc_on_unimplemented(on(aaaaaaaaaaaaaa(a, b), message = "y"))] + | ^^^^^^^^^^^^^^ expected one of `any`, `all` or `not` here, not `aaaaaaaaaaaaaa` -Some errors have detailed explanations: E0230, E0231, E0232, E0536. +error[E0232]: invalid flag in `on`-clause + --> $DIR/bad-annotation.rs:106:29 + | +LL | #[rustc_on_unimplemented(on(something, message = "y"))] + | ^^^^^^^^^ expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something` + +error: aborting due to 18 previous errors + +Some errors have detailed explanations: E0230, E0231, E0232. For more information about an error, try `rustc --explain E0230`. From 415a73e3eb4910bc40eaec8022e7bf8813523318 Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Fri, 2 May 2025 23:41:52 +0200 Subject: [PATCH 094/262] docs: alias `limit` to `Iterator::take`, cite `[u8]::utf8_chunks` in `Utf8Chunks` --- library/core/src/iter/traits/iterator.rs | 1 + library/core/src/str/lossy.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index c68fd2115d68..0d7d7860b030 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1358,6 +1358,7 @@ pub trait Iterator { /// ``` /// /// [`by_ref`]: Iterator::by_ref + #[doc(alias = "limit")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take(self, n: usize) -> Take diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index ed2cefc59a51..8d4210c80827 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -147,12 +147,14 @@ impl fmt::Debug for Debug<'_> { /// An iterator used to decode a slice of mostly UTF-8 bytes to string slices /// ([`&str`]) and byte slices ([`&[u8]`][byteslice]). /// +/// This struct is created by the [`utf8_chunks`] method on bytes slices. /// If you want a simple conversion from UTF-8 byte slices to string slices, /// [`from_utf8`] is easier to use. /// /// See the [`Utf8Chunk`] type for documentation of the items yielded by this iterator. /// /// [byteslice]: slice +/// [`utf8_chunks`]: slice::utf8_chunks /// [`from_utf8`]: super::from_utf8 /// /// # Examples From 882c74dfcf974d4129b268ca1aef4de28cd6cc4e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Apr 2025 16:52:17 +1000 Subject: [PATCH 095/262] Remove fake `BoxMarker`s. They don't appear to do anything -- no test output is affected -- and no other pretty-printing code looks like this. --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 11 +---------- compiler/rustc_hir_pretty/src/lib.rs | 9 --------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 38cadc77b777..abcbb88aab2d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -13,7 +13,7 @@ use rustc_ast::{ use crate::pp::Breaks::Inconsistent; use crate::pprust::state::fixup::FixupContext; -use crate::pprust::state::{AnnNode, BoxMarker, INDENT_UNIT, PrintState, State}; +use crate::pprust::state::{AnnNode, INDENT_UNIT, PrintState, State}; impl<'a> State<'a> { fn print_else(&mut self, els: Option<&ast::Expr>) { @@ -542,15 +542,6 @@ impl<'a> State<'a> { self.print_fn_params_and_ret(fn_decl, true); self.space(); self.print_expr(body, FixupContext::default()); - // FIXME(nnethercote): Bogus. Reduce visibility of `ended` once it's fixed. - let fake_ib = BoxMarker; - self.end(fake_ib); - - // A box will be closed by print_expr, but we didn't want an overall - // wrapper so we closed the corresponding opening. so create an - // empty box to satisfy the close. - // FIXME(nnethercote): Bogus. - let _ib = self.ibox(0); } ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 15e997aebcb8..4035de957158 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1572,15 +1572,6 @@ impl<'a> State<'a> { // This is a bare expression. self.ann.nested(self, Nested::Body(body)); - // FIXME(nnethercote): this is bogus - let fake_ib = BoxMarker; - self.end(fake_ib); - - // A box will be closed by `print_expr`, but we didn't want an overall - // wrapper so we closed the corresponding opening. so create an - // empty box to satisfy the close. - // FIXME(nnethercote): this is bogus, and `print_expr` is missing - let _ib = self.ibox(0); } hir::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { From 3896ad0acd53fa62cab711d20af8dec1f3e944a1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Apr 2025 19:59:36 +1000 Subject: [PATCH 096/262] Remove opaque type printing. As far as I can tell, this code is not actually reachable. --- compiler/rustc_hir_pretty/src/lib.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4035de957158..f4076e1114b3 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -183,7 +183,7 @@ impl<'a> State<'a> { Node::Ty(a) => self.print_type(a), Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a), Node::TraitRef(a) => self.print_trait_ref(a), - Node::OpaqueTy(o) => self.print_opaque_ty(o), + Node::OpaqueTy(_) => panic!("cannot print Node::OpaqueTy"), Node::Pat(a) => self.print_pat(a), Node::TyPat(a) => self.print_ty_pat(a), Node::PatField(a) => self.print_patfield(a), @@ -764,14 +764,6 @@ impl<'a> State<'a> { self.print_path(t.path, false); } - fn print_opaque_ty(&mut self, o: &hir::OpaqueTy<'_>) { - // FIXME(nnethercote): `cb` and `ib` are unclosed - let (_cb, _ib) = self.head("opaque"); - self.word("{"); - self.print_bounds("impl", o.bounds); - self.word("}"); - } - fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) { if !generic_params.is_empty() { self.word("for"); From 760cf8d3afd446e9a5f3dc1af006548a0da5686c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Apr 2025 20:07:10 +1000 Subject: [PATCH 097/262] Fix hir pretty-printing of `global_asm!`. One of the boxes isn't closed, and this causes everything after it to be over-indented. --- compiler/rustc_hir_pretty/src/lib.rs | 7 ++++--- tests/ui/unpretty/exhaustive-asm.hir.stdout | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index f4076e1114b3..d119402222bb 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -654,10 +654,11 @@ impl<'a> State<'a> { self.bclose(item.span, cb); } hir::ItemKind::GlobalAsm { asm, .. } => { - // FIXME(nnethercote): `ib` is unclosed - let (cb, _ib) = self.head("global_asm!"); + let (cb, ib) = self.head("global_asm!"); self.print_inline_asm(asm); - self.end(cb) + self.word(";"); + self.end(cb); + self.end(ib); } hir::ItemKind::TyAlias(ident, ty, generics) => { let (cb, ib) = self.head("type"); diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout index 5a642dff6f2e..810db69bff16 100644 --- a/tests/ui/unpretty/exhaustive-asm.hir.stdout +++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout @@ -27,5 +27,6 @@ mod expressions { mod items { /// ItemKind::GlobalAsm mod item_global_asm {/// ItemKind::GlobalAsm - global_asm! (".globl my_asm_func") } + global_asm! (".globl my_asm_func"); } +} From aa7bb1c2f5a8d8e8b709421189186e8e5e8b64f9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Apr 2025 20:17:29 +1000 Subject: [PATCH 098/262] Enable `BoxMarker` drop checking. All the box open/close issues have been fixed. --- compiler/rustc_ast_pretty/src/pp.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 142c80b8e39e..8a0dbadf18cd 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -244,9 +244,6 @@ struct BufEntry { // forgotten will trigger a panic in `drop`. (Closing a box more than once // isn't possible because `BoxMarker` doesn't implement `Copy` or `Clone`.) // -// FIXME(nnethercote): the panic in `drop` is currently disabled because a few -// places fail to close their boxes. It can be enabled once they are fixed. -// // Note: it would be better to make open/close mismatching impossible and avoid // the need for this marker type altogether by having functions like // `with_ibox` that open a box, call a closure, and then close the box. That @@ -261,8 +258,7 @@ impl !Copy for BoxMarker {} impl Drop for BoxMarker { fn drop(&mut self) { - // FIXME(nnethercote): enable once the bad cases are fixed - //panic!("BoxMarker not ended with `Printer::end()`"); + panic!("BoxMarker not ended with `Printer::end()`"); } } From e1a177bbba2b1297c33e2838f8b2b72ab5f62ecf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 Apr 2025 10:08:01 +1000 Subject: [PATCH 099/262] Improve hir pretty-printing of attributes. --- compiler/rustc_hir_pretty/src/lib.rs | 1 + tests/pretty/hir-delegation.pp | 3 +- .../attrs/automatically_derived.rs | 2 +- tests/rustdoc-json/attrs/export_name_2021.rs | 2 +- tests/rustdoc-json/attrs/export_name_2024.rs | 2 +- tests/rustdoc-json/attrs/must_use.rs | 4 +- tests/rustdoc-json/attrs/no_mangle_2021.rs | 2 +- tests/rustdoc-json/attrs/no_mangle_2024.rs | 2 +- tests/rustdoc-json/attrs/non_exhaustive.rs | 6 +-- tests/rustdoc-json/keyword_private.rs | 4 +- .../ui-fulldeps/stable-mir/check_attribute.rs | 4 +- tests/ui/unpretty/exhaustive.hir.stdout | 38 ++++++++++++++++--- 12 files changed, 49 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d119402222bb..1e260b2dda45 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -110,6 +110,7 @@ impl<'a> State<'a> { } self.print_attr_item(&unparsed, unparsed.span); self.word("]"); + self.hardbreak() } hir::Attribute::Parsed(AttributeKind::DocComment { style, kind, comment, .. }) => { self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string( diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp index 872a6a45aede..e452cee63659 100644 --- a/tests/pretty/hir-delegation.pp +++ b/tests/pretty/hir-delegation.pp @@ -2,7 +2,8 @@ //@ pretty-mode:hir //@ pp-exact:hir-delegation.pp -#![allow(incomplete_features)]#![feature(fn_delegation)] +#![allow(incomplete_features)] +#![feature(fn_delegation)] #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] diff --git a/tests/rustdoc-json/attrs/automatically_derived.rs b/tests/rustdoc-json/attrs/automatically_derived.rs index 4e1ab3d145e5..6c90d6386499 100644 --- a/tests/rustdoc-json/attrs/automatically_derived.rs +++ b/tests/rustdoc-json/attrs/automatically_derived.rs @@ -9,5 +9,5 @@ impl Default for Manual { } } -//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]' +//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]\n"]' //@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]' diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs index 254e9f6ef5bf..4e6526419bdb 100644 --- a/tests/rustdoc-json/attrs/export_name_2021.rs +++ b/tests/rustdoc-json/attrs/export_name_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]' #[export_name = "altered"] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs index 8129c109306c..f6a2a92b5bcd 100644 --- a/tests/rustdoc-json/attrs/export_name_2024.rs +++ b/tests/rustdoc-json/attrs/export_name_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024 // is still `#[export_name = ..]` without the `unsafe` attribute wrapper. -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]' #[unsafe(export_name = "altered")] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs index 64df8e5f509f..20696dce7121 100644 --- a/tests/rustdoc-json/attrs/must_use.rs +++ b/tests/rustdoc-json/attrs/must_use.rs @@ -1,9 +1,9 @@ #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]\n"]' #[must_use] pub fn example() -> impl Iterator {} -//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' +//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]\n"]' #[must_use = "does nothing if you do not use it"] pub fn explicit_message() -> impl Iterator {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs index 588be7256db5..10a372572ae5 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2021.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]' #[no_mangle] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs index 0d500e20e6c5..8f3a14cbecbf 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2024.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024 // is still `#[no_mangle]` without the `unsafe` attribute wrapper. -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]' #[unsafe(no_mangle)] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs index b95f1a8171fd..3064b86422d1 100644 --- a/tests/rustdoc-json/attrs/non_exhaustive.rs +++ b/tests/rustdoc-json/attrs/non_exhaustive.rs @@ -1,18 +1,18 @@ #![no_std] -//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]\n"]' #[non_exhaustive] pub enum MyEnum { First, } pub enum NonExhaustiveVariant { - //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' + //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]\n"]' #[non_exhaustive] Variant(i64), } -//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]\n"]' #[non_exhaustive] pub struct MyStruct { pub x: i64, diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs index fea546c9fb60..5e9a2c101636 100644 --- a/tests/rustdoc-json/keyword_private.rs +++ b/tests/rustdoc-json/keyword_private.rs @@ -5,7 +5,7 @@ //@ !has "$.index[?(@.name=='match')]" //@ has "$.index[?(@.name=='foo')]" -//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]' +//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]\n"]' //@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"' #[doc(keyword = "match")] /// this is a test! @@ -13,7 +13,7 @@ pub mod foo {} //@ !has "$.index[?(@.name=='break')]" //@ has "$.index[?(@.name=='bar')]" -//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]' +//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]\n"]' //@ is "$.index[?(@.name=='bar')].docs" '"hello"' #[doc(keyword = "break")] /// hello diff --git a/tests/ui-fulldeps/stable-mir/check_attribute.rs b/tests/ui-fulldeps/stable-mir/check_attribute.rs index 81d5399d88aa..e4cc7b104b60 100644 --- a/tests/ui-fulldeps/stable-mir/check_attribute.rs +++ b/tests/ui-fulldeps/stable-mir/check_attribute.rs @@ -35,12 +35,12 @@ fn test_stable_mir() -> ControlFlow<()> { fn test_tool(items: &CrateItems) { let rustfmt_fn = *get_item(&items, "do_not_format").unwrap(); let rustfmt_attrs = rustfmt_fn.tool_attrs(&["rustfmt".to_string(), "skip".to_string()]); - assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]"); + assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]\n"); let clippy_fn = *get_item(&items, "complex_fn").unwrap(); let clippy_attrs = clippy_fn.tool_attrs(&["clippy".to_string(), "cyclomatic_complexity".to_string()]); - assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]"); + assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]\n"); } fn get_item<'a>( diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index d2c379d43662..885135e590d2 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -8,7 +8,28 @@ // Note: the HIR revision includes a `.stderr` file because there are some // errors that only occur once we get past the AST. -#![feature(auto_traits)]#![feature(box_patterns)]#![feature(builtin_syntax)]#![feature(concat_idents)]#![feature(const_trait_impl)]#![feature(decl_macro)]#![feature(deref_patterns)]#![feature(dyn_star)]#![feature(explicit_tail_calls)]#![feature(gen_blocks)]#![feature(more_qualified_paths)]#![feature(never_patterns)]#![feature(never_type)]#![feature(pattern_types)]#![feature(pattern_type_macro)]#![feature(prelude_import)]#![feature(specialization)]#![feature(trace_macros)]#![feature(trait_alias)]#![feature(try_blocks)]#![feature(yeet_expr)]#![allow(incomplete_features)] +#![feature(auto_traits)] +#![feature(box_patterns)] +#![feature(builtin_syntax)] +#![feature(concat_idents)] +#![feature(const_trait_impl)] +#![feature(decl_macro)] +#![feature(deref_patterns)] +#![feature(dyn_star)] +#![feature(explicit_tail_calls)] +#![feature(gen_blocks)] +#![feature(more_qualified_paths)] +#![feature(never_patterns)] +#![feature(never_type)] +#![feature(pattern_types)] +#![feature(pattern_type_macro)] +#![feature(prelude_import)] +#![feature(specialization)] +#![feature(trace_macros)] +#![feature(trait_alias)] +#![feature(try_blocks)] +#![feature(yeet_expr)] +#![allow(incomplete_features)] #[prelude_import] use std::prelude::rust_2024::*; #[macro_use] @@ -33,20 +54,25 @@ mod prelude { /*! * inner multi-line doc comment */ -#[doc = "inner doc attribute"]#[allow(dead_code, unused_variables)]#[no_std] +#[doc = "inner doc attribute"] +#[allow(dead_code, unused_variables)] +#[no_std] mod attributes {//! inner single-line doc comment /*! * inner multi-line doc comment */ - #![doc = - "inner doc attribute"]#![allow(dead_code, unused_variables)]#![no_std] + #![doc = "inner doc attribute"] + #![allow(dead_code, unused_variables)] + #![no_std] /// outer single-line doc comment /** * outer multi-line doc comment */ - #[doc = - "outer doc attribute"]#[doc = "macro"]#[allow()]#[attr = Repr([ReprC])] + #[doc = "outer doc attribute"] + #[doc = "macro"] + #[allow()] + #[attr = Repr([ReprC])] struct Struct; } From 809e5b5ed17f6cede5945939bb7f10c5282d9b53 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 Apr 2025 16:05:47 +1000 Subject: [PATCH 100/262] Fix some hir pretty-printing over-indenting. --- compiler/rustc_hir_pretty/src/lib.rs | 10 ++-- tests/ui/unpretty/exhaustive.hir.stdout | 61 ++++++++++++------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1e260b2dda45..0916885cb170 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1503,7 +1503,7 @@ impl<'a> State<'a> { } hir::ExprKind::DropTemps(init) => { // Print `{`: - let cb = self.cbox(INDENT_UNIT); + let cb = self.cbox(0); let ib = self.ibox(0); self.bopen(ib); @@ -1530,12 +1530,14 @@ impl<'a> State<'a> { self.print_ident(label.ident); self.word_space(":"); } - let (cb, ib) = self.head("loop"); + let cb = self.cbox(0); + let ib = self.ibox(0); + self.word_nbsp("loop"); self.print_block(blk, cb, ib); } hir::ExprKind::Match(expr, arms, _) => { - let cb = self.cbox(INDENT_UNIT); - let ib = self.ibox(INDENT_UNIT); + let cb = self.cbox(0); + let ib = self.ibox(0); self.word_nbsp("match"); self.print_expr_as_cond(expr); self.space(); diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 885135e590d2..c1230e597ced 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -173,32 +173,32 @@ mod expressions { fn expr_for_loop() { let x; { - let _t = - match #[lang = "into_iter"](x) { - mut iter => - loop { - match #[lang = "next"](&mut iter) { - #[lang = "None"] {} => break, - #[lang = "Some"] { 0: _ } => { } - } - }, - }; - _t - }; + let _t = + match #[lang = "into_iter"](x) { + mut iter => + loop { + match #[lang = "next"](&mut iter) { + #[lang = "None"] {} => break, + #[lang = "Some"] { 0: _ } => { } + } + }, + }; + _t + }; { - let _t = - match #[lang = "into_iter"](x) { - mut iter => - 'a: - loop { - match #[lang = "next"](&mut iter) { - #[lang = "None"] {} => break, - #[lang = "Some"] { 0: _ } => { } - } - }, - }; - _t - } + let _t = + match #[lang = "into_iter"](x) { + mut iter => + 'a: + loop { + match #[lang = "next"](&mut iter) { + #[lang = "None"] {} => break, + #[lang = "Some"] { 0: _ } => { } + } + }, + }; + _t + } } /// ExprKind::Loop @@ -383,12 +383,11 @@ mod expressions { fn expr_try() { let expr; match #[lang = "branch"](expr) { - #[lang = "Break"] { 0: residual } => - #[allow(unreachable_code)] - return #[lang = "from_residual"](residual), - #[lang = "Continue"] { 0: val } => #[allow(unreachable_code)] - val, - }; + #[lang = "Break"] { 0: residual } => #[allow(unreachable_code)] + return #[lang = "from_residual"](residual), + #[lang = "Continue"] { 0: val } => #[allow(unreachable_code)] + val, + }; } /// ExprKind::Yield fn expr_yield() { yield (); yield true; } From 9af08429f13059fee07a6cb4b019e2bcda3a8093 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 Apr 2025 16:23:29 +1000 Subject: [PATCH 101/262] Avoid an indent for labelled loops. --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 4 ++-- compiler/rustc_hir_pretty/src/lib.rs | 4 ++-- tests/ui/unpretty/exhaustive.hir.stdout | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index abcbb88aab2d..c9a7e2aebd01 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -485,12 +485,12 @@ impl<'a> State<'a> { self.print_block_with_attrs(body, attrs, cb, ib); } ast::ExprKind::Loop(blk, opt_label, _) => { + let cb = self.cbox(0); + let ib = self.ibox(0); if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); } - let cb = self.cbox(0); - let ib = self.ibox(0); self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs, cb, ib); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 0916885cb170..09bf84ab64fb 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1526,12 +1526,12 @@ impl<'a> State<'a> { self.print_if(test, blk, elseopt); } hir::ExprKind::Loop(blk, opt_label, _, _) => { + let cb = self.cbox(0); + let ib = self.ibox(0); if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); } - let cb = self.cbox(0); - let ib = self.ibox(0); self.word_nbsp("loop"); self.print_block(blk, cb, ib); } diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index c1230e597ced..c20f123b16e8 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -189,8 +189,7 @@ mod expressions { let _t = match #[lang = "into_iter"](x) { mut iter => - 'a: - loop { + 'a: loop { match #[lang = "next"](&mut iter) { #[lang = "None"] {} => break, #[lang = "Some"] { 0: _ } => { } From ad3c35bea53793ff2b2f93853f688f29643db8bb Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 3 May 2025 02:47:14 +0000 Subject: [PATCH 102/262] add `ReverseSccGraph::compute` --- .../src/region_infer/reverse_sccs.rs | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index b2ed8a358279..8e04791461b2 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -7,6 +7,8 @@ use rustc_middle::ty::RegionVid; use crate::RegionInferenceContext; use crate::constraints::ConstraintSccIndex; +use crate::region_infer::ConstraintSccs; +use crate::universal_regions::UniversalRegions; pub(crate) struct ReverseSccGraph { graph: VecGraph, @@ -19,6 +21,29 @@ pub(crate) struct ReverseSccGraph { } impl ReverseSccGraph { + pub(super) fn compute( + constraint_sccs: &ConstraintSccs, + universal_regions: &UniversalRegions<'_>, + ) -> Self { + let graph = constraint_sccs.reverse(); + let mut paired_scc_regions = universal_regions + .universal_regions_iter() + .map(|region| (constraint_sccs.scc(region), region)) + .collect::>(); + paired_scc_regions.sort(); + let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect(); + + let mut scc_regions = FxIndexMap::default(); + let mut start = 0; + for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) { + let (scc, _) = chunk[0]; + + scc_regions.insert(scc, start..start + chunk.len()); + start += chunk.len(); + } + ReverseSccGraph { graph, scc_regions, universal_regions } + } + /// Find all universal regions that are required to outlive the given SCC. pub(super) fn upper_bounds(&self, scc0: ConstraintSccIndex) -> impl Iterator { let mut duplicates = FxIndexSet::default(); @@ -40,23 +65,7 @@ impl RegionInferenceContext<'_> { return; } - let graph = self.constraint_sccs.reverse(); - let mut paired_scc_regions = self - .universal_regions() - .universal_regions_iter() - .map(|region| (self.constraint_sccs.scc(region), region)) - .collect::>(); - paired_scc_regions.sort(); - let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect(); - - let mut scc_regions = FxIndexMap::default(); - let mut start = 0; - for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) { - let (scc, _) = chunk[0]; - scc_regions.insert(scc, start..start + chunk.len()); - start += chunk.len(); - } - - self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions }); + self.rev_scc_graph = + Some(ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions())); } } From 27f83a5e056a1d6d24b18a4fd257298d2e97c21a Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 3 May 2025 02:49:15 +0000 Subject: [PATCH 103/262] TypeChecker take fields by ref --- compiler/rustc_borrowck/src/type_check/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 99a544279b96..8c5122571209 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -151,8 +151,8 @@ pub(crate) fn type_check<'a, 'tcx>( body, promoted, user_type_annotations: &body.user_type_annotations, - region_bound_pairs, - known_type_outlives_obligations, + region_bound_pairs: ®ion_bound_pairs, + known_type_outlives_obligations: &known_type_outlives_obligations, reported_errors: Default::default(), universal_regions: &universal_region_relations.universal_regions, location_table, @@ -216,8 +216,8 @@ struct TypeChecker<'a, 'tcx> { /// User type annotations are shared between the main MIR and the MIR of /// all of the promoted items. user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, - region_bound_pairs: RegionBoundPairs<'tcx>, - known_type_outlives_obligations: Vec>, + region_bound_pairs: &'a RegionBoundPairs<'tcx>, + known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>], reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, universal_regions: &'a UniversalRegions<'tcx>, location_table: &'a PoloniusLocationTable, @@ -412,9 +412,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, - &self.region_bound_pairs, + self.region_bound_pairs, self.infcx.param_env, - &self.known_type_outlives_obligations, + self.known_type_outlives_obligations, locations, locations.span(self.body), category, @@ -2506,9 +2506,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, - &self.region_bound_pairs, + self.region_bound_pairs, self.infcx.param_env, - &self.known_type_outlives_obligations, + self.known_type_outlives_obligations, locations, self.body.span, // irrelevant; will be overridden. ConstraintCategory::Boring, // same as above. From 0be1ec1ccd2545785661b4beada019fcb84440f6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 3 May 2025 02:52:37 +0000 Subject: [PATCH 104/262] `CreateResult` wrap more fields in `Frozen` --- .../src/type_check/free_region_relations.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 536a27763d29..92732aba29ba 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -41,8 +41,8 @@ type NormalizedInputsAndOutput<'tcx> = Vec>; pub(crate) struct CreateResult<'tcx> { pub(crate) universal_region_relations: Frozen>, - pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, - pub(crate) known_type_outlives_obligations: Vec>, + pub(crate) region_bound_pairs: Frozen>, + pub(crate) known_type_outlives_obligations: Frozen>>, pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, } @@ -333,8 +333,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { outlives: self.outlives.freeze(), inverse_outlives: self.inverse_outlives.freeze(), }), - known_type_outlives_obligations, - region_bound_pairs: self.region_bound_pairs, + known_type_outlives_obligations: Frozen::freeze(known_type_outlives_obligations), + region_bound_pairs: Frozen::freeze(self.region_bound_pairs), normalized_inputs_and_output, } } From cbdd7134ff72aaf3679f4df2b2e4a0fe847edd06 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Sat, 12 Apr 2025 17:49:53 -0700 Subject: [PATCH 105/262] Implement Iterator::last for vec::IntoIter --- library/alloc/src/vec/into_iter.rs | 5 +++++ library/std/src/sys/args/common.rs | 4 ++-- .../tests/ui/double_ended_iterator_last.fixed | 15 ++++++++++++++- .../clippy/tests/ui/double_ended_iterator_last.rs | 15 ++++++++++++++- .../tests/ui/double_ended_iterator_last.stderr | 4 ++-- .../ui/double_ended_iterator_last_unfixable.rs | 15 ++++++++++++++- .../double_ended_iterator_last_unfixable.stderr | 4 ++-- 7 files changed, 53 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 1af110691ba6..37df928228d9 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -258,6 +258,11 @@ impl Iterator for IntoIter { self.len() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } + #[inline] fn next_chunk(&mut self) -> Result<[T; N], core::array::IntoIter> { let mut raw_ary = [const { MaybeUninit::uninit() }; N]; diff --git a/library/std/src/sys/args/common.rs b/library/std/src/sys/args/common.rs index 303b373ccf90..e787105a05a7 100644 --- a/library/std/src/sys/args/common.rs +++ b/library/std/src/sys/args/common.rs @@ -49,8 +49,8 @@ impl Iterator for Args { } #[inline] - fn last(mut self) -> Option { - self.iter.next_back() + fn last(self) -> Option { + self.iter.last() } #[inline] diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed b/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed index 2ce0c04c3017..be31ee5fb486 100644 --- a/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed +++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed @@ -84,6 +84,19 @@ fn issue_14139() { } fn drop_order() { + struct DropDeIterator(std::vec::IntoIter); + impl Iterator for DropDeIterator { + type Item = S; + fn next(&mut self) -> Option { + self.0.next() + } + } + impl DoubleEndedIterator for DropDeIterator { + fn next_back(&mut self) -> Option { + self.0.next_back() + } + } + struct S(&'static str); impl std::ops::Drop for S { fn drop(&mut self) { @@ -92,7 +105,7 @@ fn drop_order() { } let v = vec![S("one"), S("two"), S("three")]; - let mut v = v.into_iter(); + let mut v = DropDeIterator(v.into_iter()); println!("Last element is {}", v.next_back().unwrap().0); //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` println!("Done"); diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.rs b/src/tools/clippy/tests/ui/double_ended_iterator_last.rs index a4eb9b3337b9..30864e15bce7 100644 --- a/src/tools/clippy/tests/ui/double_ended_iterator_last.rs +++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.rs @@ -84,6 +84,19 @@ fn issue_14139() { } fn drop_order() { + struct DropDeIterator(std::vec::IntoIter); + impl Iterator for DropDeIterator { + type Item = S; + fn next(&mut self) -> Option { + self.0.next() + } + } + impl DoubleEndedIterator for DropDeIterator { + fn next_back(&mut self) -> Option { + self.0.next_back() + } + } + struct S(&'static str); impl std::ops::Drop for S { fn drop(&mut self) { @@ -92,7 +105,7 @@ fn drop_order() { } let v = vec![S("one"), S("two"), S("three")]; - let v = v.into_iter(); + let v = DropDeIterator(v.into_iter()); println!("Last element is {}", v.last().unwrap().0); //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` println!("Done"); diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr b/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr index fe8cf2dcb259..72a6ead47a93 100644 --- a/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr +++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr @@ -18,7 +18,7 @@ LL | let _ = DeIterator.last(); | help: try: `next_back()` error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator - --> tests/ui/double_ended_iterator_last.rs:96:36 + --> tests/ui/double_ended_iterator_last.rs:109:36 | LL | println!("Last element is {}", v.last().unwrap().0); | ^^^^^^^^ @@ -26,7 +26,7 @@ LL | println!("Last element is {}", v.last().unwrap().0); = note: this change will alter drop order which may be undesirable help: try | -LL ~ let mut v = v.into_iter(); +LL ~ let mut v = DropDeIterator(v.into_iter()); LL ~ println!("Last element is {}", v.next_back().unwrap().0); | diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs index 7c5de8832d69..e9218bbb4094 100644 --- a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs +++ b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs @@ -11,6 +11,19 @@ fn main() { } fn drop_order() { + struct DropDeIterator(std::vec::IntoIter); + impl Iterator for DropDeIterator { + type Item = S; + fn next(&mut self) -> Option { + self.0.next() + } + } + impl DoubleEndedIterator for DropDeIterator { + fn next_back(&mut self) -> Option { + self.0.next_back() + } + } + struct S(&'static str); impl std::ops::Drop for S { fn drop(&mut self) { @@ -19,7 +32,7 @@ fn drop_order() { } let v = vec![S("one"), S("two"), S("three")]; - let v = (v.into_iter(), 42); + let v = (DropDeIterator(v.into_iter()), 42); println!("Last element is {}", v.0.last().unwrap().0); //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` println!("Done"); diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr index 845afc11f042..e330a22a3548 100644 --- a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr +++ b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr @@ -1,5 +1,5 @@ error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator - --> tests/ui/double_ended_iterator_last_unfixable.rs:23:36 + --> tests/ui/double_ended_iterator_last_unfixable.rs:36:36 | LL | println!("Last element is {}", v.0.last().unwrap().0); | ^^^^------ @@ -8,7 +8,7 @@ LL | println!("Last element is {}", v.0.last().unwrap().0); | = note: this change will alter drop order which may be undesirable note: this must be made mutable to use `.next_back()` - --> tests/ui/double_ended_iterator_last_unfixable.rs:23:36 + --> tests/ui/double_ended_iterator_last_unfixable.rs:36:36 | LL | println!("Last element is {}", v.0.last().unwrap().0); | ^^^ From 1327f7034916dcfdf3038028d6a25726e0d52fef Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 3 May 2025 12:45:00 +0800 Subject: [PATCH 106/262] Improve the let code snippet --- .../ide-completion/src/completions/expr.rs | 11 ++- .../ide-completion/src/completions/keyword.rs | 96 ++++++++++++++++++- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index ee1a21f9a1a6..2245f58bc620 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -363,9 +363,14 @@ pub(crate) fn complete_expr_path( add_keyword("true", "true"); add_keyword("false", "false"); - if in_condition || in_block_expr { - add_keyword("letm", "let mut $0"); - add_keyword("let", "let $0"); + if in_condition { + add_keyword("letm", "let mut $1 = $0"); + add_keyword("let", "let $1 = $0"); + } + + if in_block_expr { + add_keyword("letm", "let mut $1 = $2;"); + add_keyword("let", "let $1 = $2;"); } if after_if_expr { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs index 039742463c81..0becdf065aca 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs @@ -336,7 +336,7 @@ fn main() { } #[test] - fn completes_let_with_space() { + fn completes_let_in_block() { check_edit( "let", r#" @@ -346,7 +346,7 @@ fn main() { "#, r#" fn main() { - let $0 + let $1 = $2; } "#, ); @@ -359,7 +359,97 @@ fn main() { "#, r#" fn main() { - let mut $0 + let mut $1 = $2; +} +"#, + ); + } + + #[test] + fn completes_let_in_condition() { + check_edit( + "let", + r#" +fn main() { + if $0 {} +} +"#, + r#" +fn main() { + if let $1 = $0 {} +} +"#, + ); + check_edit( + "letm", + r#" +fn main() { + if $0 {} +} +"#, + r#" +fn main() { + if let mut $1 = $0 {} +} +"#, + ); + } + + #[test] + fn completes_let_in_no_empty_condition() { + check_edit( + "let", + r#" +fn main() { + if $0x {} +} +"#, + r#" +fn main() { + if let $1 = $0x {} +} +"#, + ); + check_edit( + "letm", + r#" +fn main() { + if $0x {} +} +"#, + r#" +fn main() { + if let mut $1 = $0x {} +} +"#, + ); + } + + #[test] + fn completes_let_in_condition_block() { + check_edit( + "let", + r#" +fn main() { + if { $0 } {} +} +"#, + r#" +fn main() { + if { let $1 = $2; } {} +} +"#, + ); + check_edit( + "letm", + r#" +fn main() { + if { $0 } {} +} +"#, + r#" +fn main() { + if { let mut $1 = $2; } {} } "#, ); From 61488e5070b0af9697250af27df5d0aa36fe7c73 Mon Sep 17 00:00:00 2001 From: Eduard Stefes Date: Mon, 28 Apr 2025 22:25:00 +0200 Subject: [PATCH 107/262] Fix test simd/extract-insert-dyn on s390x Fix the test for s390x by enabling s390x vector extension via `target_feature(enable = "vector")`(#127506). As this is is still gated by `#![feature(s390x_target_feature)]` we need that attribute also. --- tests/codegen/simd/extract-insert-dyn.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/codegen/simd/extract-insert-dyn.rs b/tests/codegen/simd/extract-insert-dyn.rs index 7d032c6bb3ef..729f0145314a 100644 --- a/tests/codegen/simd/extract-insert-dyn.rs +++ b/tests/codegen/simd/extract-insert-dyn.rs @@ -1,6 +1,12 @@ //@compile-flags: -C opt-level=3 -C no-prepopulate-passes -#![feature(core_intrinsics, repr_simd, arm_target_feature, mips_target_feature)] +#![feature( + core_intrinsics, + repr_simd, + arm_target_feature, + mips_target_feature, + s390x_target_feature +)] #![no_std] #![crate_type = "lib"] #![allow(non_camel_case_types)] @@ -25,6 +31,7 @@ pub struct i8x16([i8; 16]); #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 { simd_extract_dyn(x, idx) } @@ -36,6 +43,7 @@ unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 { simd_extract_dyn(x, 7) } @@ -47,6 +55,7 @@ unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 { simd_extract_dyn(x, const { 3 + 4 }) } @@ -58,6 +67,7 @@ unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 { simd_extract(x, const { 3 + 4 }) } @@ -69,6 +79,7 @@ unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 { simd_insert_dyn(x, idx, e) } @@ -80,6 +91,7 @@ unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 { simd_insert_dyn(x, 7, e) } @@ -91,6 +103,7 @@ unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 { simd_insert_dyn(x, const { 3 + 4 }, e) } @@ -102,6 +115,7 @@ unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 { #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))] #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))] +#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))] unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 { simd_insert(x, const { 3 + 4 }, e) } From 7768602f97489bb47bc544f4d005e7a0f4194314 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 3 May 2025 17:03:00 +0800 Subject: [PATCH 108/262] Improve let snippet --- .../crates/ide-completion/src/completions/expr.rs | 4 ++-- .../crates/ide-completion/src/completions/keyword.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 2245f58bc620..7fbd1fbc1af4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -369,8 +369,8 @@ pub(crate) fn complete_expr_path( } if in_block_expr { - add_keyword("letm", "let mut $1 = $2;"); - add_keyword("let", "let $1 = $2;"); + add_keyword("letm", "let mut $1 = $0;"); + add_keyword("let", "let $1 = $0;"); } if after_if_expr { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs index 0becdf065aca..64bb1fce6ba0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs @@ -346,7 +346,7 @@ fn main() { "#, r#" fn main() { - let $1 = $2; + let $1 = $0; } "#, ); @@ -359,7 +359,7 @@ fn main() { "#, r#" fn main() { - let mut $1 = $2; + let mut $1 = $0; } "#, ); @@ -436,7 +436,7 @@ fn main() { "#, r#" fn main() { - if { let $1 = $2; } {} + if { let $1 = $0; } {} } "#, ); @@ -449,7 +449,7 @@ fn main() { "#, r#" fn main() { - if { let mut $1 = $2; } {} + if { let mut $1 = $0; } {} } "#, ); From 265b10fe2e411a7af34f892aaa7635fba96cce2c Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Sat, 3 May 2025 20:10:56 +0900 Subject: [PATCH 109/262] Correct warning message in restricted visibility --- compiler/rustc_middle/src/ty/mod.rs | 5 +++- tests/ui/imports/reexports.stderr | 2 +- tests/ui/pub/pub-restricted-warning.rs | 25 ++++++++++++++++++++ tests/ui/pub/pub-restricted-warning.stderr | 27 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/ui/pub/pub-restricted-warning.rs create mode 100644 tests/ui/pub/pub-restricted-warning.stderr diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index eba6d61ba7d3..112010b35082 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -297,7 +297,10 @@ impl Visibility { } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() { "pub(self)".to_string() } else { - format!("pub({})", tcx.item_name(restricted_id.to_def_id())) + format!( + "pub(in crate{})", + tcx.def_path(restricted_id.to_def_id()).to_string_no_crate_verbose() + ) } } ty::Visibility::Public => "pub".to_string(), diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index bf4ba474875b..fa05c0c0f8e8 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -62,7 +62,7 @@ warning: glob import doesn't reexport anything with visibility `pub` because no LL | pub use super::*; | ^^^^^^^^ | -note: the most public imported item is `pub(a)` +note: the most public imported item is `pub(in crate::a)` --> $DIR/reexports.rs:11:17 | LL | pub use super::*; diff --git a/tests/ui/pub/pub-restricted-warning.rs b/tests/ui/pub/pub-restricted-warning.rs new file mode 100644 index 000000000000..80384afbb008 --- /dev/null +++ b/tests/ui/pub/pub-restricted-warning.rs @@ -0,0 +1,25 @@ +//@ check-pass + +#![allow(dead_code)] + +mod outer { + pub mod inner { + pub(in crate::outer) struct Foo; + pub fn bar() -> Foo { + //~^ WARNING type `Foo` is more private than the item `outer::inner::bar` [private_interfaces] + Foo + } + } + + pub mod nested { + pub mod inner { + pub(in crate::outer::nested) struct NestedFoo; + pub fn bar() -> NestedFoo { + //~^ WARNING type `NestedFoo` is more private than the item `nested::inner::bar` [private_interfaces] + NestedFoo + } + } + } +} + +fn main() {} diff --git a/tests/ui/pub/pub-restricted-warning.stderr b/tests/ui/pub/pub-restricted-warning.stderr new file mode 100644 index 000000000000..74f32d3de3c2 --- /dev/null +++ b/tests/ui/pub/pub-restricted-warning.stderr @@ -0,0 +1,27 @@ +warning: type `Foo` is more private than the item `outer::inner::bar` + --> $DIR/pub-restricted-warning.rs:8:9 + | +LL | pub fn bar() -> Foo { + | ^^^^^^^^^^^^^^^^^^^ function `outer::inner::bar` is reachable at visibility `pub(crate)` + | +note: but type `Foo` is only usable at visibility `pub(in crate::outer)` + --> $DIR/pub-restricted-warning.rs:7:9 + | +LL | pub(in crate::outer) struct Foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default + +warning: type `NestedFoo` is more private than the item `nested::inner::bar` + --> $DIR/pub-restricted-warning.rs:17:13 + | +LL | pub fn bar() -> NestedFoo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `nested::inner::bar` is reachable at visibility `pub(crate)` + | +note: but type `NestedFoo` is only usable at visibility `pub(in crate::outer::nested)` + --> $DIR/pub-restricted-warning.rs:16:13 + | +LL | pub(in crate::outer::nested) struct NestedFoo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 2 warnings emitted + From 74a17fd049885f8b2c9d1e570a3afea364415d84 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 3 May 2025 15:18:30 +0200 Subject: [PATCH 110/262] Have `AstValidation` track a linting node id --- compiler/rustc_ast_passes/src/ast_validation.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 1feb3e9bf9b4..f57f06f37a7b 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -82,6 +82,8 @@ struct AstValidator<'a> { /// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe. extern_mod_safety: Option, + lint_node_id: NodeId, + lint_buffer: &'a mut LintBuffer, } @@ -839,6 +841,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.has_proc_macro_decls = true; } + let previous_lint_node_id = mem::replace(&mut self.lint_node_id, item.id); + if let Some(ident) = item.kind.ident() && attr::contains_name(&item.attrs, sym::no_mangle) { @@ -1128,6 +1132,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } _ => visit::walk_item(self, item), } + + self.lint_node_id = previous_lint_node_id; } fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { @@ -1694,6 +1700,7 @@ pub fn check_crate( outer_impl_trait_span: None, disallow_tilde_const: Some(TildeConstReason::Item), extern_mod_safety: None, + lint_node_id: CRATE_NODE_ID, lint_buffer: lints, }; visit::walk_crate(&mut validator, krate); From f4e1ec111c016f1dbbedb2628a30e9ce20d8e5f1 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 3 May 2025 15:19:08 +0200 Subject: [PATCH 111/262] Report the `unsafe_attr_outside_unsafe` lint at the closest node --- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_expand/src/config.rs | 7 ++++++- compiler/rustc_expand/src/expand.rs | 6 +++++- compiler/rustc_parse/src/validate_attr.rs | 16 +++++++++++----- .../unsafe-attributes/unsafe-attributes-allow.rs | 16 ++++++++++++++++ 5 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index f57f06f37a7b..9b64bcc6df44 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -828,7 +828,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_attribute(&mut self, attr: &Attribute) { - validate_attr::check_attr(&self.sess.psess, attr); + validate_attr::check_attr(&self.sess.psess, attr, self.lint_node_id); } fn visit_ty(&mut self, ty: &'a Ty) { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 2df3281568be..02af26b01567 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -274,7 +274,12 @@ impl<'a> StripUnconfigured<'a> { /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect. pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec { - validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr); + validate_attr::check_attribute_safety( + &self.sess.psess, + AttributeSafety::Normal, + &cfg_attr, + ast::CRATE_NODE_ID, + ); // A trace attribute left in AST in place of the original `cfg_attr` attribute. // It can later be used by lints or other diagnostics. diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 1f430b0018f5..d4853d1357f3 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1983,7 +1983,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let mut span: Option = None; while let Some(attr) = attrs.next() { rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features); - validate_attr::check_attr(&self.cx.sess.psess, attr); + validate_attr::check_attr( + &self.cx.sess.psess, + attr, + self.cx.current_expansion.lint_node_id, + ); let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span }; span = Some(current_span); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 6a1c2af48ed5..aa29b24fe910 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -3,7 +3,8 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; use rustc_ast::{ - self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety, + self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, NodeId, + Safety, }; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; @@ -15,7 +16,7 @@ use rustc_span::{Span, Symbol, sym}; use crate::{errors, parse_in}; -pub fn check_attr(psess: &ParseSess, attr: &Attribute) { +pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) { if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace) { return; @@ -26,7 +27,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { // All non-builtin attributes are considered safe let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal); - check_attribute_safety(psess, safety, attr); + check_attribute_safety(psess, safety, attr, id); // Check input tokens for built-in and key-value attributes. match attr_info { @@ -154,7 +155,12 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte } } -pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: &Attribute) { +pub fn check_attribute_safety( + psess: &ParseSess, + safety: AttributeSafety, + attr: &Attribute, + id: NodeId, +) { let attr_item = attr.get_normal_item(); if let AttributeSafety::Unsafe { unsafe_since } = safety { @@ -185,7 +191,7 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: psess.buffer_lint( UNSAFE_ATTR_OUTSIDE_UNSAFE, path_span, - ast::CRATE_NODE_ID, + id, BuiltinLintDiag::UnsafeAttrOutsideUnsafe { attribute_name_span: path_span, sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()), diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs new file mode 100644 index 000000000000..76fdce7e5cff --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ edition: 2021 +// +// Anti-regression test for https://github.com/rust-lang/rust/issues/140602 +// where the generated warning couldn't be allowed due too being attached to +// the wrong AST node. + +#![deny(unsafe_attr_outside_unsafe)] + +#[allow(unsafe_attr_outside_unsafe)] +mod generated { + #[no_mangle] + fn _generated_foo() {} +} + +fn main() {} From 873ca5fa04b79da80ca779e0e577f06a07cea8d3 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 2 May 2025 22:34:30 +0800 Subject: [PATCH 112/262] Just suggest positional arg and adjust issue0139104 ui test Signed-off-by: xizheyin --- compiler/rustc_parse_format/src/lib.rs | 116 +++++++---------- .../invalid-parse-format-issue-139104.rs | 17 ++- .../invalid-parse-format-issue-139104.stderr | 122 ++++++++++++------ 3 files changed, 147 insertions(+), 108 deletions(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index c356a97a55a2..999e71592745 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -918,73 +918,57 @@ impl<'a> Parser<'a> { } fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) { - // If the argument is an identifier, it may be a field access. - if arg.is_identifier() { - if let Some(end) = self.consume_pos('.') { - let byte_pos = self.to_span_index(end); - let start = InnerOffset(byte_pos.0 + 1); - let field = self.argument(start); - // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any - // deeper nesting, or another type of expression, like method calls, are not supported - if !self.consume('}') { - return; - } - if let ArgumentNamed(_) = arg.position { - match field.position { - ArgumentNamed(_) => { - self.errors.insert( - 0, - ParseError { - description: "field access isn't supported".to_string(), - note: None, - label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), - secondary_label: None, - suggestion: Suggestion::UsePositional, - }, - ); - } - ArgumentIs(_) => { - self.errors.insert( - 0, - ParseError { - description: "tuple index access isn't supported".to_string(), - note: None, - label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), - secondary_label: None, - suggestion: Suggestion::UsePositional, - }, - ); - } - _ => {} - }; - } - } - } else if matches!(arg.position, ArgumentNamed(_) | ArgumentIs(_)) { - let arg_name = match arg.position { - ArgumentNamed(arg_name) => &format!("`{arg_name}`"), - ArgumentIs(arg_index) => &format!("at index `{arg_index}`"), - _ => unreachable!(), - }; + // If the argument is not an identifier, it is not a field access. + if !arg.is_identifier() { + return; + } - self.errors.insert( - 0, - ParseError { - description: format!("invalid format string for argument {}", arg_name), - note: None, - label: format!("invalid format specifier for this argument"), - span: InnerSpan::new(arg.position_span.start, arg.position_span.end), - secondary_label: None, - suggestion: Suggestion::None, - }, - ); + if let Some(end) = self.consume_pos('.') { + let byte_pos = self.to_span_index(end); + let start = InnerOffset(byte_pos.0 + 1); + let field = self.argument(start); + // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any + // deeper nesting, or another type of expression, like method calls, are not supported + if !self.consume('}') { + return; + } + if let ArgumentNamed(_) = arg.position { + match field.position { + ArgumentNamed(_) => { + self.errors.insert( + 0, + ParseError { + description: "field access isn't supported".to_string(), + note: None, + label: "not supported".to_string(), + span: InnerSpan::new( + arg.position_span.start, + field.position_span.end, + ), + secondary_label: None, + suggestion: Suggestion::UsePositional, + }, + ); + } + ArgumentIs(_) => { + self.errors.insert( + 0, + ParseError { + description: "tuple index access isn't supported".to_string(), + note: None, + label: "not supported".to_string(), + span: InnerSpan::new( + arg.position_span.start, + field.position_span.end, + ), + secondary_label: None, + suggestion: Suggestion::UsePositional, + }, + ); + } + _ => {} + }; + } } } diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs index 0809235bb6dd..7644df8be49a 100644 --- a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs @@ -1,8 +1,13 @@ fn main() { - println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` - println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` - println!("xxx{0:_1.4}", 1.11); //~ ERROR invalid format string: invalid format string for argument at index `0` - println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: invalid format string for argument `foo` - println!("xxx{0:_1.4", 1.11); //~ ERROR invalid format string: invalid format string for argument at index `0` - println!("xxx{ 0", 1.11); //~ ERROR invalid format string: expected `}`, found `0` + println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.` + println!("{0:_1.4}", 1.11); //~ ERROR invalid format string: expected `}`, found `.` + println!("{:_1.4}", 3.14); //~ ERROR invalid format string: expected `}`, found `.` + + println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.` + println!("{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.` + println!("{:_1.4", 3.14); //~ ERROR invalid format string: expected `}`, found `.` + + println!("{ 0", 1.11); //~ ERROR invalid format string: expected `}`, found `0` + println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.` + println!("{0:1.4_1.4}", 3.14); //~ ERROR invalid format string: expected `}`, found `.` } diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr index ceae8d051e5e..202aa450cab7 100644 --- a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr +++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr @@ -1,42 +1,92 @@ -error: invalid format string: invalid format string for argument `foo` - --> $DIR/invalid-parse-format-issue-139104.rs:2:16 +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:2:22 | LL | println!("{foo:_1.4}", foo = 3.14); - | ^^^ invalid format specifier for this argument in format string - -error: invalid format string: invalid format string for argument `foo` - --> $DIR/invalid-parse-format-issue-139104.rs:3:16 - | -LL | println!("{foo:1.4_1.4}", foo = 3.14); - | ^^^ invalid format specifier for this argument in format string - -error: invalid format string: invalid format string for argument at index `0` - --> $DIR/invalid-parse-format-issue-139104.rs:4:19 - | -LL | println!("xxx{0:_1.4}", 1.11); - | ^ invalid format specifier for this argument in format string - -error: invalid format string: invalid format string for argument `foo` - --> $DIR/invalid-parse-format-issue-139104.rs:5:16 - | -LL | println!("{foo:_1.4", foo = 3.14); - | ^^^ invalid format specifier for this argument in format string - -error: invalid format string: invalid format string for argument at index `0` - --> $DIR/invalid-parse-format-issue-139104.rs:6:19 - | -LL | println!("xxx{0:_1.4", 1.11); - | ^ invalid format specifier for this argument in format string - -error: invalid format string: expected `}`, found `0` - --> $DIR/invalid-parse-format-issue-139104.rs:7:21 - | -LL | println!("xxx{ 0", 1.11); - | - ^ expected `}` in format string - | | - | because of this opening brace + | - ^ expected `}` in format string + | | + | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: aborting due to 6 previous errors +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:3:20 + | +LL | println!("{0:_1.4}", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:4:19 + | +LL | println!("{:_1.4}", 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:6:22 + | +LL | println!("{foo:_1.4", foo = 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:7:20 + | +LL | println!("{0:_1.4", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:8:19 + | +LL | println!("{:_1.4", 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `0` + --> $DIR/invalid-parse-format-issue-139104.rs:10:18 + | +LL | println!("{ 0", 1.11); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:11:25 + | +LL | println!("{foo:1.4_1.4}", foo = 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `.` + --> $DIR/invalid-parse-format-issue-139104.rs:12:23 + | +LL | println!("{0:1.4_1.4}", 3.14); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + +error: aborting due to 9 previous errors From a6cac47500a43ff872475801a83a70c414e756a1 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 May 2025 23:29:00 +0800 Subject: [PATCH 113/262] tests: fix a panic strategy in `cfg_false_no_std-2.rs` To avoid having target-dependent "unwinding panics are not supported without std" errors, without regressing test intention. --- tests/ui/cfg/cfg_false_no_std-2.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs index 18b2c699fd7a..666c90deaf0f 100644 --- a/tests/ui/cfg/cfg_false_no_std-2.rs +++ b/tests/ui/cfg/cfg_false_no_std-2.rs @@ -1,7 +1,11 @@ // Error, the linked empty library is `no_std` and doesn't provide a panic handler. -//@ dont-require-annotations: ERROR //@ dont-check-compiler-stderr + +// NOTE: fix a panic strategy to prevent differing errors subject to target's default panic strategy +// which changes between targets. The specific panic strategy doesn't matter for test intention. +//@ compile-flags: -Cpanic=abort + //@ aux-build: cfg_false_lib_no_std_before.rs #![no_std] @@ -11,6 +15,3 @@ extern crate cfg_false_lib_no_std_before as _; fn main() {} //~? 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 From cb73af3e2da60268e8f5f67871870a86b9fff23d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 May 2025 23:40:31 +0800 Subject: [PATCH 114/262] tests: explain why `two-panic-runtimes.rs` ignores target-dependent errors --- tests/ui/panic-runtime/two-panic-runtimes.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/ui/panic-runtime/two-panic-runtimes.rs b/tests/ui/panic-runtime/two-panic-runtimes.rs index 80591edd1077..de76578a267f 100644 --- a/tests/ui/panic-runtime/two-panic-runtimes.rs +++ b/tests/ui/panic-runtime/two-panic-runtimes.rs @@ -1,11 +1,19 @@ // ignore-tidy-linelength //@ build-fail -//@ dont-require-annotations: ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ aux-build:panic-runtime-unwind2.rs //@ aux-build:panic-runtime-lang-items.rs +// NOTE: there can be additional errors regarding trying to mix this crate if the precompiled target +// (such as `wasm32-unknown-unknown` currently unconditionally defaulting to panic=abort) panic +// strategy differs to abort, then involving a potentially-unwinding `panic_runtime_unwind` that +// uses a different panic strategy. These errors are important but not to the test intention, which +// is to check that trying to bring two panic runtimes (`panic_runtime_unwind`) and +// (`panic_runtime_unwind2`) is prohibited. As such, the additional errors are not checked in this +// test. +//@ dont-require-annotations: ERROR + #![no_std] #![no_main] @@ -16,7 +24,3 @@ extern crate panic_runtime_lang_items; fn main() {} //~? 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` From 3ea420a697d4fe73c1348d40dac02718fcfccbd9 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 May 2025 23:44:07 +0800 Subject: [PATCH 115/262] tests: justify why `want-abort-got-unwind{,2}.rs` ignore additional errors --- tests/ui/panic-runtime/want-abort-got-unwind.rs | 12 +++++++----- tests/ui/panic-runtime/want-abort-got-unwind2.rs | 16 +++++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/ui/panic-runtime/want-abort-got-unwind.rs b/tests/ui/panic-runtime/want-abort-got-unwind.rs index 42cdf8bc6626..7a6bd011d9e4 100644 --- a/tests/ui/panic-runtime/want-abort-got-unwind.rs +++ b/tests/ui/panic-runtime/want-abort-got-unwind.rs @@ -1,16 +1,18 @@ // ignore-tidy-linelength //@ build-fail -//@ dont-require-annotations: ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ compile-flags:-C panic=abort +// NOTE: depending on the target's default panic strategy, there can be additional errors that +// complain about linking two panic runtimes (e.g. precompiled `panic_unwind` if target default +// panic strategy is unwind, in addition to `panic_runtime_unwind`). These additional errors will +// not be observed on targets whose default panic strategy is abort, where `panic_abort` is linked +// in instead. +//@ dont-require-annotations: ERROR + extern crate panic_runtime_unwind; fn main() {} //~? 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 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 ddf12cd2a9a5..da239a675e5b 100644 --- a/tests/ui/panic-runtime/want-abort-got-unwind2.rs +++ b/tests/ui/panic-runtime/want-abort-got-unwind2.rs @@ -1,17 +1,23 @@ // ignore-tidy-linelength //@ build-fail -//@ dont-require-annotations: ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ aux-build:wants-panic-runtime-unwind.rs //@ compile-flags:-C panic=abort +// Like `want-abort-got-unwind.rs`, this version checks that if the root binary wants abort panic +// runtime, that the compiler rejects a setup where a dependency crate in the dependency DAG +// transitively provides an unwind panic runtime (which also is built with `-Cpanic=unwind`, making +// that potentially-unwinding). + +// NOTE: similar to `want-abort-got-unwind.rs`, there can be additional errors if the target default +// panic strategy is unwind, because then the precompiled `panic_unwind` would also be linked in, +// duplicating `panic_runtime_unwind` (transitively). But those additional errors are not important +// to test intention. +//@ dont-require-annotations: ERROR + extern crate wants_panic_runtime_unwind; fn main() {} //~? 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 crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort` From 48b72c52f35be9d4d0c6ee4c42487354b73d931e Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 May 2025 23:34:59 +0800 Subject: [PATCH 116/262] tests: add FIXME issue for `debuginfo-type-name-layout-ice-94961-2.rs` --- .../debuginfo/debuginfo-type-name-layout-ice-94961-2.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs index b79b5ff6fdb1..08f8ae391fdb 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -1,4 +1,6 @@ -//FIXME~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture +// ignore-tidy-linelength +// FIXME(#140620)~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture + // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that // causes a layout error. // This version of the test already ICE'd before the commit that introduce the ICE described in @@ -18,5 +20,5 @@ pub fn foo() -> usize { std::mem::size_of::>() } -// FIXME: the error is reported on different lines on different targets -//FIXME~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture +// FIXME(#140620): the error is reported on different lines on different targets +//FIXME(#140620)~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture From 9a574b0871746808d292f4f945b7854342118f35 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 3 May 2025 17:22:52 +0200 Subject: [PATCH 117/262] Move some tests out of tests/ui --- src/tools/tidy/src/issues.txt | 10 --- .../no_link/auxiliary/empty-crate-1.rs} | 2 - .../no_link/auxiliary/empty-crate-2.rs} | 0 .../no_link/auxiliary/no_link-crate.rs | 6 ++ .../no_link/multiple-crates-and-no_link.rs | 17 +++++ .../no_link/no-link-unknown-crate.rs | 19 +++++ .../no_link}/no-link-unknown-crate.stderr | 2 +- tests/ui/auxiliary/inner_static.rs | 51 -------------- tests/ui/auxiliary/issue-13560-3.rs | 6 -- .../auxiliary/inline-cross-crate.rs} | 0 .../llvm-miscompile-MarkValue-MaybeLive.rs} | 0 tests/ui/cross-crate/inline-cross-crate.rs | 12 ++++ .../llvm-miscompile-MarkValue-MaybeLive.rs | 22 ++++++ tests/ui/impl-privacy-xc-1.rs | 10 --- tests/ui/inner-static.rs | 14 ---- tests/ui/issue-13560.rs | 13 ---- tests/ui/issue-18502.rs | 8 --- tests/ui/issue-24106.rs | 8 --- tests/ui/issue-76387-llvm-miscompile.rs | 21 ------ .../ui/{ => macros}/auxiliary/fancy-panic.rs | 0 tests/ui/{ => macros}/non-fmt-panic.fixed | 6 ++ tests/ui/{ => macros}/non-fmt-panic.rs | 6 ++ tests/ui/{ => macros}/non-fmt-panic.stderr | 70 +++++++++---------- tests/ui/no-link-unknown-crate.rs | 4 -- .../auxiliary/cross-crate-enum-pattern.rs} | 0 tests/ui/pattern/cross-crate-enum-pattern.rs | 13 ++++ .../auxiliary/impl-privacy-cross-crate-1.rs} | 0 ..._xc_2.rs => impl-privacy-cross-crate-2.rs} | 0 .../ui/privacy/impl-privacy-cross-crate-1.rs | 10 +++ .../ui/privacy/impl-privacy-cross-crate-2.rs | 10 +++ tests/ui/privacy/impl-privacy-xc-2.rs | 10 --- tests/ui/statics/auxiliary/inner_static.rs | 67 ++++++++++++++++++ tests/ui/statics/inner-static.rs | 30 ++++++++ 33 files changed, 254 insertions(+), 193 deletions(-) rename tests/ui/{auxiliary/issue-13560-1.rs => attributes/no_link/auxiliary/empty-crate-1.rs} (52%) rename tests/ui/{auxiliary/issue-13560-2.rs => attributes/no_link/auxiliary/empty-crate-2.rs} (100%) create mode 100644 tests/ui/attributes/no_link/auxiliary/no_link-crate.rs create mode 100644 tests/ui/attributes/no_link/multiple-crates-and-no_link.rs create mode 100644 tests/ui/attributes/no_link/no-link-unknown-crate.rs rename tests/ui/{ => attributes/no_link}/no-link-unknown-crate.stderr (85%) delete mode 100644 tests/ui/auxiliary/inner_static.rs delete mode 100644 tests/ui/auxiliary/issue-13560-3.rs rename tests/ui/{auxiliary/issue-18502.rs => cross-crate/auxiliary/inline-cross-crate.rs} (100%) rename tests/ui/{auxiliary/issue-76387.rs => cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs} (100%) create mode 100644 tests/ui/cross-crate/inline-cross-crate.rs create mode 100644 tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs delete mode 100644 tests/ui/impl-privacy-xc-1.rs delete mode 100644 tests/ui/inner-static.rs delete mode 100644 tests/ui/issue-13560.rs delete mode 100644 tests/ui/issue-18502.rs delete mode 100644 tests/ui/issue-24106.rs delete mode 100644 tests/ui/issue-76387-llvm-miscompile.rs rename tests/ui/{ => macros}/auxiliary/fancy-panic.rs (100%) rename tests/ui/{ => macros}/non-fmt-panic.fixed (94%) rename tests/ui/{ => macros}/non-fmt-panic.rs (94%) rename tests/ui/{ => macros}/non-fmt-panic.stderr (93%) delete mode 100644 tests/ui/no-link-unknown-crate.rs rename tests/ui/{auxiliary/issue-24106.rs => pattern/auxiliary/cross-crate-enum-pattern.rs} (100%) create mode 100644 tests/ui/pattern/cross-crate-enum-pattern.rs rename tests/ui/{auxiliary/impl_privacy_xc_1.rs => privacy/auxiliary/impl-privacy-cross-crate-1.rs} (100%) rename tests/ui/privacy/auxiliary/{impl_privacy_xc_2.rs => impl-privacy-cross-crate-2.rs} (100%) create mode 100644 tests/ui/privacy/impl-privacy-cross-crate-1.rs create mode 100644 tests/ui/privacy/impl-privacy-cross-crate-2.rs delete mode 100644 tests/ui/privacy/impl-privacy-xc-2.rs create mode 100644 tests/ui/statics/auxiliary/inner_static.rs create mode 100644 tests/ui/statics/inner-static.rs diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index e6b5aa59622d..2f0158609e08 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -276,13 +276,7 @@ ui/auto-traits/issue-23080-2.rs ui/auto-traits/issue-23080.rs ui/auto-traits/issue-83857-ub.rs ui/auto-traits/issue-84075.rs -ui/auxiliary/issue-13560-1.rs -ui/auxiliary/issue-13560-2.rs -ui/auxiliary/issue-13560-3.rs ui/auxiliary/issue-16822.rs -ui/auxiliary/issue-18502.rs -ui/auxiliary/issue-24106.rs -ui/auxiliary/issue-76387.rs ui/bench/issue-32062.rs ui/binding/issue-40402-1.rs ui/binding/issue-40402-2.rs @@ -1378,12 +1372,8 @@ ui/intrinsics/issue-28575.rs ui/intrinsics/issue-84297-reifying-copy.rs ui/invalid/issue-114435-layout-type-err.rs ui/issue-11881.rs -ui/issue-13560.rs ui/issue-15924.rs ui/issue-16822.rs -ui/issue-18502.rs -ui/issue-24106.rs -ui/issue-76387-llvm-miscompile.rs ui/issues-71798.rs ui/issues/auxiliary/issue-11224.rs ui/issues/auxiliary/issue-11508.rs diff --git a/tests/ui/auxiliary/issue-13560-1.rs b/tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs similarity index 52% rename from tests/ui/auxiliary/issue-13560-1.rs rename to tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs index baca1567e1b0..8bd2b3353b8f 100644 --- a/tests/ui/auxiliary/issue-13560-1.rs +++ b/tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs @@ -1,3 +1 @@ -//@ no-prefer-dynamic - #![crate_type = "dylib"] diff --git a/tests/ui/auxiliary/issue-13560-2.rs b/tests/ui/attributes/no_link/auxiliary/empty-crate-2.rs similarity index 100% rename from tests/ui/auxiliary/issue-13560-2.rs rename to tests/ui/attributes/no_link/auxiliary/empty-crate-2.rs diff --git a/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs b/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs new file mode 100644 index 000000000000..1c3af5431cc6 --- /dev/null +++ b/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs @@ -0,0 +1,6 @@ +//@ no-prefer-dynamic + +#![crate_type = "rlib"] + +#[macro_use] #[no_link] extern crate empty_crate_1 as t1; +#[macro_use] extern crate empty_crate_2 as t2; diff --git a/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs b/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs new file mode 100644 index 000000000000..0e6f1deb2172 --- /dev/null +++ b/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs @@ -0,0 +1,17 @@ +//! Regression test for #13560. Previously, it was possible to +//! trigger an assert in crate numbering if a series of crates +//! being loaded included a "syntax-only" extern crate. +//! But it appears we don't mess with crate numbering for +//! `#[no_link]` crates anymore, so this test doesn't seem +//! to test anything now. + +//@ run-pass +//@ needs-crate-type: dylib +//@ aux-build:empty-crate-1.rs +//@ aux-build:empty-crate-2.rs +//@ aux-build:no_link-crate.rs + +extern crate empty_crate_2 as t2; +extern crate no_link_crate as t3; + +fn main() {} diff --git a/tests/ui/attributes/no_link/no-link-unknown-crate.rs b/tests/ui/attributes/no_link/no-link-unknown-crate.rs new file mode 100644 index 000000000000..3a91fa27ee3b --- /dev/null +++ b/tests/ui/attributes/no_link/no-link-unknown-crate.rs @@ -0,0 +1,19 @@ +//! Unfortunately the development of `#[phase]` and `#[no_link]` +//! predates Zulip, and thus has been lost in the sands of time. +//! Understanding the true nature of this test has been left as +//! an exercise for the reader. +//! +//! But we guess from the git history that originally this +//! test was supposed to check that we error if we can't find +//! an extern crate annotated with `#[phase(syntax)]`, +//! see `macro-crate-unknown-crate.rs` in +//! . Later, we changed +//! `#[phase]` to `#![feature(plugin)]` and added a `#[no_link]`. +//! +//! I suppose that this now tests that we still error if we can't +//! find a `#[no_link]` extern crate? + +#[no_link] +extern crate doesnt_exist; //~ ERROR can't find crate + +fn main() {} diff --git a/tests/ui/no-link-unknown-crate.stderr b/tests/ui/attributes/no_link/no-link-unknown-crate.stderr similarity index 85% rename from tests/ui/no-link-unknown-crate.stderr rename to tests/ui/attributes/no_link/no-link-unknown-crate.stderr index edc248db09ea..999b013866cd 100644 --- a/tests/ui/no-link-unknown-crate.stderr +++ b/tests/ui/attributes/no_link/no-link-unknown-crate.stderr @@ -1,5 +1,5 @@ error[E0463]: can't find crate for `doesnt_exist` - --> $DIR/no-link-unknown-crate.rs:2:1 + --> $DIR/no-link-unknown-crate.rs:17:1 | LL | extern crate doesnt_exist; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate diff --git a/tests/ui/auxiliary/inner_static.rs b/tests/ui/auxiliary/inner_static.rs deleted file mode 100644 index 42dcd379d41e..000000000000 --- a/tests/ui/auxiliary/inner_static.rs +++ /dev/null @@ -1,51 +0,0 @@ -pub struct A { pub v: T } -pub struct B { pub v: T } - -pub mod test { - pub struct A { pub v: T } - - impl A { - pub fn foo(&self) -> isize { - static a: isize = 5; - return a - } - - pub fn bar(&self) -> isize { - static a: isize = 6; - return a; - } - } -} - -impl A { - pub fn foo(&self) -> isize { - static a: isize = 1; - return a - } - - pub fn bar(&self) -> isize { - static a: isize = 2; - return a; - } -} - -impl B { - pub fn foo(&self) -> isize { - static a: isize = 3; - return a - } - - pub fn bar(&self) -> isize { - static a: isize = 4; - return a; - } -} - -pub fn foo() -> isize { - let a = A { v: () }; - let b = B { v: () }; - let c = test::A { v: () }; - return a.foo() + a.bar() + - b.foo() + b.bar() + - c.foo() + c.bar(); -} diff --git a/tests/ui/auxiliary/issue-13560-3.rs b/tests/ui/auxiliary/issue-13560-3.rs deleted file mode 100644 index 4aab2ddc73a0..000000000000 --- a/tests/ui/auxiliary/issue-13560-3.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ no-prefer-dynamic - -#![crate_type = "rlib"] - -#[macro_use] #[no_link] extern crate issue_13560_1 as t1; -#[macro_use] extern crate issue_13560_2 as t2; diff --git a/tests/ui/auxiliary/issue-18502.rs b/tests/ui/cross-crate/auxiliary/inline-cross-crate.rs similarity index 100% rename from tests/ui/auxiliary/issue-18502.rs rename to tests/ui/cross-crate/auxiliary/inline-cross-crate.rs diff --git a/tests/ui/auxiliary/issue-76387.rs b/tests/ui/cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs similarity index 100% rename from tests/ui/auxiliary/issue-76387.rs rename to tests/ui/cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs diff --git a/tests/ui/cross-crate/inline-cross-crate.rs b/tests/ui/cross-crate/inline-cross-crate.rs new file mode 100644 index 000000000000..273aa8f8f0d8 --- /dev/null +++ b/tests/ui/cross-crate/inline-cross-crate.rs @@ -0,0 +1,12 @@ +//! Dpn't ice on using an inlined function from another crate +//! See and +//! + +//@ run-pass +//@ aux-build:inline-cross-crate.rs + +extern crate inline_cross_crate as fmt; + +fn main() { + ::fmt::baz(); +} diff --git a/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs b/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs new file mode 100644 index 000000000000..95d022ddd96e --- /dev/null +++ b/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs @@ -0,0 +1,22 @@ +//! Regression test for +//! Tests that LLVM doesn't miscompile this +//! See upstream fix: . + +//@ compile-flags: -C opt-level=3 +//@ aux-build: llvm-miscompile-MarkValue-MaybeLive.rs +//@ run-pass + +extern crate llvm_miscompile_MarkValue_MaybeLive; + +use llvm_miscompile_MarkValue_MaybeLive::FatPtr; + +fn print(data: &[u8]) { + println!("{:#?}", data); +} + +fn main() { + let ptr = FatPtr::new(20); + let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr(), ptr.len()) }; + + print(data); +} diff --git a/tests/ui/impl-privacy-xc-1.rs b/tests/ui/impl-privacy-xc-1.rs deleted file mode 100644 index 6a10986739cd..000000000000 --- a/tests/ui/impl-privacy-xc-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:impl_privacy_xc_1.rs - - -extern crate impl_privacy_xc_1; - -pub fn main() { - let fish = impl_privacy_xc_1::Fish { x: 1 }; - fish.swim(); -} diff --git a/tests/ui/inner-static.rs b/tests/ui/inner-static.rs deleted file mode 100644 index 9455ec5712fe..000000000000 --- a/tests/ui/inner-static.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -//@ aux-build:inner_static.rs - - -extern crate inner_static; - -pub fn main() { - let a = inner_static::A::<()> { v: () }; - let b = inner_static::B::<()> { v: () }; - let c = inner_static::test::A::<()> { v: () }; - assert_eq!(a.bar(), 2); - assert_eq!(b.bar(), 4); - assert_eq!(c.bar(), 6); -} diff --git a/tests/ui/issue-13560.rs b/tests/ui/issue-13560.rs deleted file mode 100644 index 6174fa9324b1..000000000000 --- a/tests/ui/issue-13560.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -//@ ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) -//@ aux-build:issue-13560-1.rs -//@ aux-build:issue-13560-2.rs -//@ aux-build:issue-13560-3.rs - -// Regression test for issue #13560, the test itself is all in the dependent -// libraries. The fail which previously failed to compile is the one numbered 3. - -extern crate issue_13560_2 as t2; -extern crate issue_13560_3 as t3; - -fn main() {} diff --git a/tests/ui/issue-18502.rs b/tests/ui/issue-18502.rs deleted file mode 100644 index 3e2c37ee8aa9..000000000000 --- a/tests/ui/issue-18502.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -//@ aux-build:issue-18502.rs - -extern crate issue_18502 as fmt; - -fn main() { - ::fmt::baz(); -} diff --git a/tests/ui/issue-24106.rs b/tests/ui/issue-24106.rs deleted file mode 100644 index 4f7b299b12f5..000000000000 --- a/tests/ui/issue-24106.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -//@ aux-build:issue-24106.rs - -extern crate issue_24106; - -fn main() { - issue_24106::go::<()>(); -} diff --git a/tests/ui/issue-76387-llvm-miscompile.rs b/tests/ui/issue-76387-llvm-miscompile.rs deleted file mode 100644 index d674ebb5eaf1..000000000000 --- a/tests/ui/issue-76387-llvm-miscompile.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ compile-flags: -C opt-level=3 -//@ aux-build: issue-76387.rs -//@ run-pass - -// Regression test for issue #76387 -// Tests that LLVM doesn't miscompile this - -extern crate issue_76387; - -use issue_76387::FatPtr; - -fn print(data: &[u8]) { - println!("{:#?}", data); -} - -fn main() { - let ptr = FatPtr::new(20); - let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr(), ptr.len()) }; - - print(data); -} diff --git a/tests/ui/auxiliary/fancy-panic.rs b/tests/ui/macros/auxiliary/fancy-panic.rs similarity index 100% rename from tests/ui/auxiliary/fancy-panic.rs rename to tests/ui/macros/auxiliary/fancy-panic.rs diff --git a/tests/ui/non-fmt-panic.fixed b/tests/ui/macros/non-fmt-panic.fixed similarity index 94% rename from tests/ui/non-fmt-panic.fixed rename to tests/ui/macros/non-fmt-panic.fixed index fa9a1ad89bdd..b102dba17319 100644 --- a/tests/ui/non-fmt-panic.fixed +++ b/tests/ui/macros/non-fmt-panic.fixed @@ -1,3 +1,9 @@ +//! The non_fmt_panics lint detects panic!(..) invocations where +//! the first argument is not a formatting string. +//! +//! Also, this test checks that this is not emitted if it originates +//! in an external macro. + //@ run-rustfix //@ rustfix-only-machine-applicable //@ build-pass (FIXME(62277): should be check-pass) diff --git a/tests/ui/non-fmt-panic.rs b/tests/ui/macros/non-fmt-panic.rs similarity index 94% rename from tests/ui/non-fmt-panic.rs rename to tests/ui/macros/non-fmt-panic.rs index 451a0c76018c..9277529c6d42 100644 --- a/tests/ui/non-fmt-panic.rs +++ b/tests/ui/macros/non-fmt-panic.rs @@ -1,3 +1,9 @@ +//! The non_fmt_panics lint detects panic!(..) invocations where +//! the first argument is not a formatting string. +//! +//! Also, this test checks that this is not emitted if it originates +//! in an external macro. + //@ run-rustfix //@ rustfix-only-machine-applicable //@ build-pass (FIXME(62277): should be check-pass) diff --git a/tests/ui/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr similarity index 93% rename from tests/ui/non-fmt-panic.stderr rename to tests/ui/macros/non-fmt-panic.stderr index 0134a8ddf292..30b63cb46e22 100644 --- a/tests/ui/non-fmt-panic.stderr +++ b/tests/ui/macros/non-fmt-panic.stderr @@ -1,5 +1,5 @@ warning: panic message contains a brace - --> $DIR/non-fmt-panic.rs:13:29 + --> $DIR/non-fmt-panic.rs:19:29 | LL | panic!("here's a brace: {"); | ^ @@ -12,7 +12,7 @@ LL | panic!("{}", "here's a brace: {"); | +++++ warning: panic message contains a brace - --> $DIR/non-fmt-panic.rs:14:35 + --> $DIR/non-fmt-panic.rs:20:35 | LL | unreachable!("here's a brace: {"); | ^ @@ -24,7 +24,7 @@ LL | unreachable!("{}", "here's a brace: {"); | +++++ warning: panic message contains a brace - --> $DIR/non-fmt-panic.rs:15:31 + --> $DIR/non-fmt-panic.rs:21:31 | LL | std::panic!("another one: }"); | ^ @@ -36,7 +36,7 @@ LL | std::panic!("{}", "another one: }"); | +++++ warning: panic message contains an unused formatting placeholder - --> $DIR/non-fmt-panic.rs:16:25 + --> $DIR/non-fmt-panic.rs:22:25 | LL | core::panic!("Hello {}"); | ^^ @@ -52,7 +52,7 @@ LL | core::panic!("{}", "Hello {}"); | +++++ warning: panic message contains unused formatting placeholders - --> $DIR/non-fmt-panic.rs:17:21 + --> $DIR/non-fmt-panic.rs:23:21 | LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ @@ -68,7 +68,7 @@ LL | assert!(false, "{}", "{:03x} {test} bla"); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:19:20 + --> $DIR/non-fmt-panic.rs:25:20 | LL | assert!(false, S); | ^ @@ -81,7 +81,7 @@ LL | assert!(false, "{}", S); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:21:20 + --> $DIR/non-fmt-panic.rs:27:20 | LL | assert!(false, 123); | ^^^ @@ -94,7 +94,7 @@ LL | assert!(false, "{}", 123); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:23:20 + --> $DIR/non-fmt-panic.rs:29:20 | LL | assert!(false, Some(123)); | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | assert!(false, "{:?}", Some(123)); | +++++++ warning: panic message contains braces - --> $DIR/non-fmt-panic.rs:25:27 + --> $DIR/non-fmt-panic.rs:31:27 | LL | debug_assert!(false, "{{}} bla"); | ^^^^ @@ -119,7 +119,7 @@ LL | debug_assert!(false, "{}", "{{}} bla"); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:26:12 + --> $DIR/non-fmt-panic.rs:32:12 | LL | panic!(C); | ^ @@ -132,7 +132,7 @@ LL | panic!("{}", C); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:27:12 + --> $DIR/non-fmt-panic.rs:33:12 | LL | panic!(S); | ^ @@ -145,7 +145,7 @@ LL | panic!("{}", S); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:28:18 + --> $DIR/non-fmt-panic.rs:34:18 | LL | unreachable!(S); | ^ @@ -158,7 +158,7 @@ LL | unreachable!("{}", S); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:29:18 + --> $DIR/non-fmt-panic.rs:35:18 | LL | unreachable!(S); | ^ @@ -171,7 +171,7 @@ LL | unreachable!("{}", S); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:30:17 + --> $DIR/non-fmt-panic.rs:36:17 | LL | std::panic!(123); | ^^^ @@ -189,7 +189,7 @@ LL + std::panic::panic_any(123); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:31:18 + --> $DIR/non-fmt-panic.rs:37:18 | LL | core::panic!(&*"abc"); | ^^^^^^^ @@ -202,7 +202,7 @@ LL | core::panic!("{}", &*"abc"); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:32:12 + --> $DIR/non-fmt-panic.rs:38:12 | LL | panic!(Some(123)); | ^^^^^^^^^ @@ -220,7 +220,7 @@ LL + std::panic::panic_any(Some(123)); | warning: panic message contains an unused formatting placeholder - --> $DIR/non-fmt-panic.rs:33:12 + --> $DIR/non-fmt-panic.rs:39:12 | LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ @@ -236,7 +236,7 @@ LL | panic!("{}", concat!("{", "}")); | +++++ warning: panic message contains braces - --> $DIR/non-fmt-panic.rs:34:5 + --> $DIR/non-fmt-panic.rs:40:5 | LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -248,7 +248,7 @@ LL | panic!("{}", concat!("{", "{")); | +++++ warning: panic message contains an unused formatting placeholder - --> $DIR/non-fmt-panic.rs:36:37 + --> $DIR/non-fmt-panic.rs:42:37 | LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ @@ -256,7 +256,7 @@ LL | fancy_panic::fancy_panic!("test {} 123"); = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:46:12 + --> $DIR/non-fmt-panic.rs:52:12 | LL | panic!(a!()); | ^^^^ @@ -274,7 +274,7 @@ LL + std::panic::panic_any(a!()); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:47:18 + --> $DIR/non-fmt-panic.rs:53:18 | LL | unreachable!(a!()); | ^^^^ @@ -287,7 +287,7 @@ LL | unreachable!("{}", a!()); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:49:12 + --> $DIR/non-fmt-panic.rs:55:12 | LL | panic!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ @@ -302,7 +302,7 @@ LL + panic!("{}", 1); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:50:18 + --> $DIR/non-fmt-panic.rs:56:18 | LL | unreachable!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ @@ -317,7 +317,7 @@ LL + unreachable!("{}", 1); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:51:20 + --> $DIR/non-fmt-panic.rs:57:20 | LL | assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ @@ -332,7 +332,7 @@ LL + assert!(false, "{}", 1); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:52:26 + --> $DIR/non-fmt-panic.rs:58:26 | LL | debug_assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL + debug_assert!(false, "{}", 1); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:54:12 + --> $DIR/non-fmt-panic.rs:60:12 | LL | panic![123]; | ^^^ @@ -365,7 +365,7 @@ LL + std::panic::panic_any(123); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:55:12 + --> $DIR/non-fmt-panic.rs:61:12 | LL | panic!{123}; | ^^^ @@ -383,7 +383,7 @@ LL + std::panic::panic_any(123); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:72:12 + --> $DIR/non-fmt-panic.rs:78:12 | LL | panic!(v); | ------ ^ @@ -394,7 +394,7 @@ LL | panic!(v); = note: for more information, see warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:73:20 + --> $DIR/non-fmt-panic.rs:79:20 | LL | assert!(false, v); | ^ @@ -403,7 +403,7 @@ LL | assert!(false, v); = note: for more information, see warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:77:12 + --> $DIR/non-fmt-panic.rs:83:12 | LL | panic!(v); | ^ @@ -421,7 +421,7 @@ LL + std::panic::panic_any(v); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:78:20 + --> $DIR/non-fmt-panic.rs:84:20 | LL | assert!(false, v); | ^ @@ -434,7 +434,7 @@ LL | assert!(false, "{:?}", v); | +++++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:82:12 + --> $DIR/non-fmt-panic.rs:88:12 | LL | panic!(v); | ^ @@ -452,7 +452,7 @@ LL + std::panic::panic_any(v); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:83:20 + --> $DIR/non-fmt-panic.rs:89:20 | LL | assert!(false, v); | ^ @@ -465,7 +465,7 @@ LL | assert!(false, "{}", v); | +++++ warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:87:12 + --> $DIR/non-fmt-panic.rs:93:12 | LL | panic!(v); | ^ @@ -483,7 +483,7 @@ LL + std::panic::panic_any(v); | warning: panic message is not a string literal - --> $DIR/non-fmt-panic.rs:88:20 + --> $DIR/non-fmt-panic.rs:94:20 | LL | assert!(false, v); | ^ diff --git a/tests/ui/no-link-unknown-crate.rs b/tests/ui/no-link-unknown-crate.rs deleted file mode 100644 index c7da2e41832f..000000000000 --- a/tests/ui/no-link-unknown-crate.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[no_link] -extern crate doesnt_exist; //~ ERROR can't find crate - -fn main() {} diff --git a/tests/ui/auxiliary/issue-24106.rs b/tests/ui/pattern/auxiliary/cross-crate-enum-pattern.rs similarity index 100% rename from tests/ui/auxiliary/issue-24106.rs rename to tests/ui/pattern/auxiliary/cross-crate-enum-pattern.rs diff --git a/tests/ui/pattern/cross-crate-enum-pattern.rs b/tests/ui/pattern/cross-crate-enum-pattern.rs new file mode 100644 index 000000000000..254caf99277c --- /dev/null +++ b/tests/ui/pattern/cross-crate-enum-pattern.rs @@ -0,0 +1,13 @@ +//! Test that we can match on enum constants across crates. +//! +//! Regression test for . + + +//@ run-pass +//@ aux-build:cross-crate-enum-pattern.rs + +extern crate cross_crate_enum_pattern; + +fn main() { + cross_crate_enum_pattern::go::<()>(); +} diff --git a/tests/ui/auxiliary/impl_privacy_xc_1.rs b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-1.rs similarity index 100% rename from tests/ui/auxiliary/impl_privacy_xc_1.rs rename to tests/ui/privacy/auxiliary/impl-privacy-cross-crate-1.rs diff --git a/tests/ui/privacy/auxiliary/impl_privacy_xc_2.rs b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-2.rs similarity index 100% rename from tests/ui/privacy/auxiliary/impl_privacy_xc_2.rs rename to tests/ui/privacy/auxiliary/impl-privacy-cross-crate-2.rs diff --git a/tests/ui/privacy/impl-privacy-cross-crate-1.rs b/tests/ui/privacy/impl-privacy-cross-crate-1.rs new file mode 100644 index 000000000000..6b2ef3ccc781 --- /dev/null +++ b/tests/ui/privacy/impl-privacy-cross-crate-1.rs @@ -0,0 +1,10 @@ +//@ run-pass +//@ aux-build:impl-privacy-cross-crate-1.rs + + +extern crate impl_privacy_cross_crate_1; + +pub fn main() { + let fish = impl_privacy_cross_crate_1::Fish { x: 1 }; + fish.swim(); +} diff --git a/tests/ui/privacy/impl-privacy-cross-crate-2.rs b/tests/ui/privacy/impl-privacy-cross-crate-2.rs new file mode 100644 index 000000000000..fa07e6e8ccea --- /dev/null +++ b/tests/ui/privacy/impl-privacy-cross-crate-2.rs @@ -0,0 +1,10 @@ +//@ run-pass +//@ aux-build:impl-privacy-cross-crate-2.rs + +extern crate impl_privacy_cross_crate_2; + +pub fn main() { + let fish1 = impl_privacy_cross_crate_2::Fish { x: 1 }; + let fish2 = impl_privacy_cross_crate_2::Fish { x: 2 }; + if fish1.eq(&fish2) { println!("yes") } else { println!("no") }; +} diff --git a/tests/ui/privacy/impl-privacy-xc-2.rs b/tests/ui/privacy/impl-privacy-xc-2.rs deleted file mode 100644 index da345ba20720..000000000000 --- a/tests/ui/privacy/impl-privacy-xc-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:impl_privacy_xc_2.rs - -extern crate impl_privacy_xc_2; - -pub fn main() { - let fish1 = impl_privacy_xc_2::Fish { x: 1 }; - let fish2 = impl_privacy_xc_2::Fish { x: 2 }; - if fish1.eq(&fish2) { println!("yes") } else { println!("no") }; -} diff --git a/tests/ui/statics/auxiliary/inner_static.rs b/tests/ui/statics/auxiliary/inner_static.rs new file mode 100644 index 000000000000..1c62046438fc --- /dev/null +++ b/tests/ui/statics/auxiliary/inner_static.rs @@ -0,0 +1,67 @@ +//! Test for inner statics with the same name. +//! +//! Before, the path name for all items defined in methods of traits and impls never +//! took into account the name of the method. This meant that if you had two statics +//! of the same name in two different methods the statics would end up having the +//! same symbol named (even after mangling) because the path components leading to +//! the symbol were exactly the same (just __extensions__ and the static name). +//! +//! It turns out that if you add the symbol "A" twice to LLVM, it automatically +//! makes the second one "A1" instead of "A". What this meant is that in local crate +//! compilations we never found this bug. Even across crates, this was never a +//! problem. The problem arises when you have generic methods that don't get +//! generated at compile-time of a library. If the statics were re-added to LLVM by +//! a client crate of a library in a different order, you would reference different +//! constants (the integer suffixes wouldn't be guaranteed to be the same). + +pub struct A { pub v: T } +pub struct B { pub v: T } + +pub mod test { + pub struct A { pub v: T } + + impl A { + pub fn foo(&self) -> isize { + static a: isize = 5; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 6; + return a; + } + } +} + +impl A { + pub fn foo(&self) -> isize { + static a: isize = 1; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 2; + return a; + } +} + +impl B { + pub fn foo(&self) -> isize { + static a: isize = 3; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 4; + return a; + } +} + +pub fn foo() -> isize { + let a = A { v: () }; + let b = B { v: () }; + let c = test::A { v: () }; + return a.foo() + a.bar() + + b.foo() + b.bar() + + c.foo() + c.bar(); +} diff --git a/tests/ui/statics/inner-static.rs b/tests/ui/statics/inner-static.rs new file mode 100644 index 000000000000..1916435c46a1 --- /dev/null +++ b/tests/ui/statics/inner-static.rs @@ -0,0 +1,30 @@ +//! Test for inner statics with the same name. +//! +//! Before, the path name for all items defined in methods of traits and impls never +//! took into account the name of the method. This meant that if you had two statics +//! of the same name in two different methods the statics would end up having the +//! same symbol named (even after mangling) because the path components leading to +//! the symbol were exactly the same (just __extensions__ and the static name). +//! +//! It turns out that if you add the symbol "A" twice to LLVM, it automatically +//! makes the second one "A1" instead of "A". What this meant is that in local crate +//! compilations we never found this bug. Even across crates, this was never a +//! problem. The problem arises when you have generic methods that don't get +//! generated at compile-time of a library. If the statics were re-added to LLVM by +//! a client crate of a library in a different order, you would reference different +//! constants (the integer suffixes wouldn't be guaranteed to be the same). + +//@ run-pass +//@ aux-build:inner_static.rs + + +extern crate inner_static; + +pub fn main() { + let a = inner_static::A::<()> { v: () }; + let b = inner_static::B::<()> { v: () }; + let c = inner_static::test::A::<()> { v: () }; + assert_eq!(a.bar(), 2); + assert_eq!(b.bar(), 4); + assert_eq!(c.bar(), 6); +} From 5cbb27ff90b6685a27492dc2b1a23074e6194f9a Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Sat, 3 May 2025 16:29:22 +0000 Subject: [PATCH 118/262] Suggest `retain_mut` over `retain` as `Vec::extract_if` alternative --- library/alloc/src/vec/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 65a83cb98ba6..72279e12192b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3659,9 +3659,9 @@ impl Vec { /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. - /// Use [`retain`] with a negated predicate if you do not need the returned iterator. + /// Use [`retain_mut`] with a negated predicate if you do not need the returned iterator. /// - /// [`retain`]: Vec::retain + /// [`retain_mut`]: Vec::retain_mut /// /// Using this method is equivalent to the following code: /// From 9aee0aa453a83f8bee6dc32037e0389f3a9188fe Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 3 May 2025 19:10:43 +0200 Subject: [PATCH 119/262] allow `#[rustfmt::skip]` in combination with `#[naked]` --- compiler/rustc_passes/src/check_attr.rs | 4 +++- tests/ui/asm/naked-functions.rs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f04b167889f1..e5b20901c0c2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -683,7 +683,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if !other_attr.has_any_name(ALLOW_LIST) { + if !other_attr.has_any_name(ALLOW_LIST) + && !matches!(other_attr.path().as_slice(), [sym::rustfmt, ..]) + { let path = other_attr.path(); let path: Vec<_> = path.iter().map(|s| s.as_str()).collect(); let other_attr_name = path.join("::"); diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index cb5fde9a80b8..a6f41698b411 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -231,3 +231,9 @@ pub extern "C" fn compatible_linkage() { pub extern "C" fn rustc_std_internal_symbol() { naked_asm!("", options(raw)); } + +#[rustfmt::skip] +#[unsafe(naked)] +pub extern "C" fn rustfmt_skip() { + naked_asm!("", options(raw)); +} From 00d3fdce7cb36a8c3fa090f797bdd093665cbe93 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 May 2025 09:57:20 -0700 Subject: [PATCH 120/262] Allow linking rustc and rustdoc against the same single tracing crate By consecutively initializing `tracing` and `rustc_log`, Rustdoc assumes that these involve 2 different tracing crates. I would like to be able to build rustdoc against the same tracing crate that rustc_log is also built against. Previously this arrangement would crash rustdoc: thread 'main' panicked at rust/compiler/rustc_log/src/lib.rs:142:65: called `Result::unwrap()` on an `Err` value: SetGlobalDefaultError("a global default trace dispatcher has already been set") stack backtrace: 0: rust_begin_unwind 1: core::panicking::panic_fmt 2: core::result::unwrap_failed 3: rustc_log::init_logger 4: rustc_driver_impl::init_logger 5: rustdoc::main note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. error: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md note: please make sure that you have updated to the latest nightly query stack during panic: end of query stack --- compiler/rustc_log/src/lib.rs | 13 +++++++++++-- src/librustdoc/lib.rs | 26 +++++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 49dd388f14cc..1bb502ca3d06 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -37,6 +37,7 @@ use std::env::{self, VarError}; use std::fmt::{self, Display}; use std::io::{self, IsTerminal}; +use tracing::dispatcher::SetGlobalDefaultError; use tracing_core::{Event, Subscriber}; use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter}; use tracing_subscriber::fmt::FmtContext; @@ -131,10 +132,10 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { .without_time() .event_format(BacktraceFormatter { backtrace_target }); let subscriber = subscriber.with(fmt_layer); - tracing::subscriber::set_global_default(subscriber).unwrap(); + tracing::subscriber::set_global_default(subscriber)?; } Err(_) => { - tracing::subscriber::set_global_default(subscriber).unwrap(); + tracing::subscriber::set_global_default(subscriber)?; } }; @@ -180,6 +181,7 @@ pub enum Error { InvalidColorValue(String), NonUnicodeColorValue, InvalidWraptree(String), + AlreadyInit(SetGlobalDefaultError), } impl std::error::Error for Error {} @@ -199,6 +201,13 @@ impl Display for Error { formatter, "invalid log WRAPTREE value '{value}': expected a non-negative integer", ), + Error::AlreadyInit(tracing_error) => Display::fmt(tracing_error, formatter), } } } + +impl From for Error { + fn from(tracing_error: SetGlobalDefaultError) -> Self { + Error::AlreadyInit(tracing_error) + } +} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 44bd96a7e450..bca40b8117bd 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -170,12 +170,28 @@ pub fn main() { // NOTE: this compiles both versions of tracing unconditionally, because // - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and // - Otherwise, there's no warning that logging is being ignored when `download-rustc` is enabled - // NOTE: The reason this doesn't show double logging when `download-rustc = false` and - // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one - // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml). - init_logging(&early_dcx); - rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")); + crate::init_logging(&early_dcx); + match rustc_log::init_logger(rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")) { + Ok(()) => {} + // With `download-rustc = true` there are definitely 2 distinct tracing crates in the + // dependency graph: one in the downloaded sysroot and one built just now as a dependency of + // rustdoc. So the sysroot's tracing is definitely not yet initialized here. + // + // But otherwise, depending on link style, there may or may not be 2 tracing crates in play. + // The one we just initialized in `crate::init_logging` above is rustdoc's direct dependency + // on tracing. When rustdoc is built by x.py using Cargo, rustc_driver's and rustc_log's + // tracing dependency is distinct from this one and also needs to be initialized (using the + // same RUSTDOC_LOG environment variable for both). Other build systems may use just a + // single tracing crate throughout the rustc and rustdoc build. + // + // The reason initializing 2 tracings does not show double logging when `download-rustc = + // false` and `debug_logging = true` is because all rustc logging goes only to its version + // of tracing (the one in the sysroot) and all of rustdoc's logging only goes to its version + // (the one in Cargo.toml). + Err(rustc_log::Error::AlreadyInit(_)) => {} + Err(error) => early_dcx.early_fatal(error.to_string()), + } let exit_code = rustc_driver::catch_with_exit_code(|| { let at_args = rustc_driver::args::raw_args(&early_dcx); From 879b12e2ce3dc14ca2bc40ac1311e8f2bac19048 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 May 2025 14:10:58 +0300 Subject: [PATCH 121/262] compiletest: Do not require annotations on empty labels and suggestions --- src/tools/compiletest/src/json.rs | 23 +-- tests/incremental/circular-dependencies.rs | 1 - .../const_in_pattern/reject_non_structural.rs | 1 - .../reject_non_structural.stderr | 8 +- tests/ui/fn/param-mismatch-foreign.rs | 1 - tests/ui/fn/param-mismatch-foreign.stderr | 2 +- ...signature-error-reporting-under-verbose.rs | 1 - ...ature-error-reporting-under-verbose.stderr | 2 +- tests/ui/issues/issue-48131.rs | 4 +- tests/ui/issues/issue-48131.stderr | 2 +- .../dont-point-return-on-E0308.rs | 1 - .../dont-point-return-on-E0308.stderr | 2 +- .../similar_paths_primitive.rs | 3 +- .../similar_paths_primitive.stderr | 6 +- .../numeric-suffix/numeric-suffix-i32.fixed | 11 -- .../numeric-suffix/numeric-suffix-i32.rs | 11 -- .../numeric-suffix/numeric-suffix-i32.stderr | 22 +-- .../numeric-suffix/numeric-suffix-i64.fixed | 11 -- .../numeric-suffix/numeric-suffix-i64.rs | 11 -- .../numeric-suffix/numeric-suffix-i64.stderr | 22 +-- .../numeric-suffix/numeric-suffix-isize.fixed | 11 -- .../numeric-suffix/numeric-suffix-isize.rs | 11 -- .../numeric-suffix-isize.stderr | 22 +-- .../numeric-suffix/numeric-suffix-u32.fixed | 11 -- .../numeric-suffix/numeric-suffix-u32.rs | 11 -- .../numeric-suffix/numeric-suffix-u32.stderr | 22 +-- .../numeric-suffix/numeric-suffix-u64.fixed | 11 -- .../numeric-suffix/numeric-suffix-u64.rs | 11 -- .../numeric-suffix/numeric-suffix-u64.stderr | 22 +-- .../numeric-suffix/numeric-suffix-usize.fixed | 11 -- .../numeric-suffix/numeric-suffix-usize.rs | 11 -- .../numeric-suffix-usize.stderr | 22 +-- .../numeric-suffix/numeric-suffix.fixed | 69 --------- .../numeric/numeric-suffix/numeric-suffix.rs | 69 --------- .../numeric-suffix/numeric-suffix.stderr | 136 +++++++++--------- tests/ui/parser/fn-arg-doc-comment.rs | 3 - tests/ui/parser/fn-arg-doc-comment.stderr | 10 +- .../const-async-const.rs | 1 - .../several-kw-jump.rs | 1 - .../issue-78123-non-exhaustive-reference.rs | 1 - ...ssue-78123-non-exhaustive-reference.stderr | 2 +- .../type/type-check/point-at-inference-4.rs | 1 - .../type-check/point-at-inference-4.stderr | 4 +- 43 files changed, 168 insertions(+), 450 deletions(-) diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 960f5ba58882..151ac345125e 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -181,8 +181,6 @@ fn push_actual_errors( .filter(|(_, span)| Path::new(&span.file_name) == Path::new(&file_name)) .collect(); - let spans_in_this_file: Vec<_> = spans_info_in_this_file.iter().map(|(_, span)| span).collect(); - let primary_spans: Vec<_> = spans_info_in_this_file .iter() .filter(|(is_primary, _)| *is_primary) @@ -280,7 +278,9 @@ fn push_actual_errors( line_num: Some(span.line_start + index), kind: ErrorKind::Suggestion, msg: line.to_string(), - require_annotation: true, + // Empty suggestions (suggestions to remove something) are common + // and annotating them in source is not useful. + require_annotation: !line.is_empty(), }); } } @@ -294,13 +294,16 @@ fn push_actual_errors( } // Add notes for any labels that appear in the message. - for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) { - errors.push(Error { - line_num: Some(span.line_start), - kind: ErrorKind::Note, - msg: span.label.clone().unwrap(), - require_annotation: true, - }); + for (_, span) in spans_info_in_this_file { + if let Some(label) = &span.label { + errors.push(Error { + line_num: Some(span.line_start), + kind: ErrorKind::Note, + msg: label.clone(), + // Empty labels (only underlining spans) are common and do not need annotations. + require_annotation: !label.is_empty(), + }); + } } // Flatten out the children. diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs index bd3b109b62c7..c7b5b931fbbe 100644 --- a/tests/incremental/circular-dependencies.rs +++ b/tests/incremental/circular-dependencies.rs @@ -15,7 +15,6 @@ pub struct Foo; pub fn consume_foo(_: Foo) {} //[cfail2]~^ NOTE function defined here -//[cfail2]~| NOTE pub fn produce_foo() -> Foo { Foo diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index 6478bf9c6ee1..39e5f732a898 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -93,7 +93,6 @@ fn main() { //~| NOTE constant of non-structural type trait Trait: Sized { const ASSOC: Option; } //~ NOTE constant defined here - //~^ NOTE impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; //~^ ERROR constant of non-structural type `NoDerive` in a pattern diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index bf54d3d76aed..fa16d0b06a7f 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -118,14 +118,14 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:98:28 + --> $DIR/reject_non_structural.rs:97:28 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns ... LL | trait Trait: Sized { const ASSOC: Option; } | ------------------ ------------------------- constant defined here -... +LL | impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ constant of non-structural type | @@ -136,7 +136,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:103:28 + --> $DIR/reject_non_structural.rs:102:28 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns @@ -153,7 +153,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:108:29 + --> $DIR/reject_non_structural.rs:107:29 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns diff --git a/tests/ui/fn/param-mismatch-foreign.rs b/tests/ui/fn/param-mismatch-foreign.rs index eebca29d6c93..2ab2bf95448a 100644 --- a/tests/ui/fn/param-mismatch-foreign.rs +++ b/tests/ui/fn/param-mismatch-foreign.rs @@ -1,7 +1,6 @@ extern "C" { fn foo(x: i32, y: u32, z: i32); //~^ NOTE function defined here - //~| NOTE } fn main() { diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr index fff3283cbb6c..835e0a3343e9 100644 --- a/tests/ui/fn/param-mismatch-foreign.stderr +++ b/tests/ui/fn/param-mismatch-foreign.stderr @@ -1,5 +1,5 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied - --> $DIR/param-mismatch-foreign.rs:8:5 + --> $DIR/param-mismatch-foreign.rs:7:5 | LL | foo(1i32, 2i32); | ^^^ ---- argument #2 of type `u32` is missing diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.rs b/tests/ui/fn/signature-error-reporting-under-verbose.rs index 4a72da789789..0047d452b7a6 100644 --- a/tests/ui/fn/signature-error-reporting-under-verbose.rs +++ b/tests/ui/fn/signature-error-reporting-under-verbose.rs @@ -4,7 +4,6 @@ fn foo(_: i32, _: i32) {} fn needs_ptr(_: fn(i32, u32)) {} //~^ NOTE function defined here -//~| NOTE fn main() { needs_ptr(foo); diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.stderr b/tests/ui/fn/signature-error-reporting-under-verbose.stderr index 6c6a313c4df7..d9ccec23fcb6 100644 --- a/tests/ui/fn/signature-error-reporting-under-verbose.stderr +++ b/tests/ui/fn/signature-error-reporting-under-verbose.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/signature-error-reporting-under-verbose.rs:10:15 + --> $DIR/signature-error-reporting-under-verbose.rs:9:15 | LL | needs_ptr(foo); | --------- ^^^ expected fn pointer, found fn item diff --git a/tests/ui/issues/issue-48131.rs b/tests/ui/issues/issue-48131.rs index 85664e62eade..a1084ea243b2 100644 --- a/tests/ui/issues/issue-48131.rs +++ b/tests/ui/issues/issue-48131.rs @@ -1,13 +1,12 @@ // This note is annotated because the purpose of the test // is to ensure that certain other notes are not generated. -#![deny(unused_unsafe)] //~ NOTE +#![deny(unused_unsafe)] // (test that no note is generated on this unsafe fn) pub unsafe fn a() { fn inner() { unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe` - //~^ NOTE } inner() @@ -18,7 +17,6 @@ pub fn b() { unsafe { fn inner() { unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe` - //~^ NOTE } // `()` is fine to zero-initialize as it is zero sized and inhabited. let () = ::std::mem::zeroed(); diff --git a/tests/ui/issues/issue-48131.stderr b/tests/ui/issues/issue-48131.stderr index 5acc4f16e9fc..fe0cd4efae89 100644 --- a/tests/ui/issues/issue-48131.stderr +++ b/tests/ui/issues/issue-48131.stderr @@ -11,7 +11,7 @@ LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/issue-48131.rs:20:13 + --> $DIR/issue-48131.rs:19:13 | LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.rs b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs index dca917e3ba1e..750329d29c00 100644 --- a/tests/ui/mismatched_types/dont-point-return-on-E0308.rs +++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs @@ -2,7 +2,6 @@ async fn f(_: &()) {} //~^ NOTE function defined here -//~| NOTE // Second note is the span of the underlined argument, I think... fn main() { diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr index 9d4852cff8c6..105dc5c2e798 100644 --- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr +++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dont-point-return-on-E0308.rs:11:11 + --> $DIR/dont-point-return-on-E0308.rs:10:11 | LL | f(()); | - ^^ expected `&()`, found `()` diff --git a/tests/ui/mismatched_types/similar_paths_primitive.rs b/tests/ui/mismatched_types/similar_paths_primitive.rs index b20ca80ac071..a58fe68b8638 100644 --- a/tests/ui/mismatched_types/similar_paths_primitive.rs +++ b/tests/ui/mismatched_types/similar_paths_primitive.rs @@ -4,9 +4,8 @@ struct bool; //~ NOTE the other `bool` is defined in the current crate struct str; //~ NOTE the other `str` is defined in the current crate fn foo(_: bool) {} //~ NOTE function defined here - //~^ NOTE fn bar(_: &str) {} //~ NOTE function defined here - //~^ NOTE + fn main() { foo(true); //~^ ERROR mismatched types [E0308] diff --git a/tests/ui/mismatched_types/similar_paths_primitive.stderr b/tests/ui/mismatched_types/similar_paths_primitive.stderr index 9c1aa0d7105b..cf26234dba85 100644 --- a/tests/ui/mismatched_types/similar_paths_primitive.stderr +++ b/tests/ui/mismatched_types/similar_paths_primitive.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/similar_paths_primitive.rs:11:9 + --> $DIR/similar_paths_primitive.rs:10:9 | LL | foo(true); | --- ^^^^ expected `bool`, found a different `bool` @@ -20,7 +20,7 @@ LL | fn foo(_: bool) {} | ^^^ ------- error[E0308]: mismatched types - --> $DIR/similar_paths_primitive.rs:17:9 + --> $DIR/similar_paths_primitive.rs:16:9 | LL | bar("hello"); | --- ^^^^^^^ expected `str`, found a different `str` @@ -35,7 +35,7 @@ note: the other `str` is defined in the current crate LL | struct str; | ^^^^^^^^^^ note: function defined here - --> $DIR/similar_paths_primitive.rs:8:4 + --> $DIR/similar_paths_primitive.rs:7:4 | LL | fn bar(_: &str) {} | ^^^ ------- diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed index e3b613cc3f64..9f891afc313a 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_i32); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs index 3b384e763107..a735fade86ed 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr index 6c6b8b51c226..b3450b41d38c 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:28:16 + --> $DIR/numeric-suffix-i32.rs:17:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `i32`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:32:16 + --> $DIR/numeric-suffix-i32.rs:21:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `i32`, found `u64` @@ -37,7 +37,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:36:16 + --> $DIR/numeric-suffix-i32.rs:25:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `i32`, found `u32` @@ -56,7 +56,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:40:16 + --> $DIR/numeric-suffix-i32.rs:29:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `i32`, found `u16` @@ -75,7 +75,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:44:16 + --> $DIR/numeric-suffix-i32.rs:33:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `i32`, found `u8` @@ -94,7 +94,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:48:16 + --> $DIR/numeric-suffix-i32.rs:37:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `i32`, found `isize` @@ -113,7 +113,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:52:16 + --> $DIR/numeric-suffix-i32.rs:41:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `i32`, found `i64` @@ -132,7 +132,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:57:16 + --> $DIR/numeric-suffix-i32.rs:46:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `i32`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:61:16 + --> $DIR/numeric-suffix-i32.rs:50:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `i32`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:65:16 + --> $DIR/numeric-suffix-i32.rs:54:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `i32`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42i32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i32.rs:69:16 + --> $DIR/numeric-suffix-i32.rs:58:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `i32`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed index 0fcda6c1f806..6d1c585a5639 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_i64); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs index 9c912bc38dad..fd4862be3873 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr index 7c26dd7be1c6..63326f49a8f0 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:28:16 + --> $DIR/numeric-suffix-i64.rs:17:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `i64`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:32:16 + --> $DIR/numeric-suffix-i64.rs:21:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `i64`, found `u64` @@ -37,7 +37,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:36:16 + --> $DIR/numeric-suffix-i64.rs:25:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `i64`, found `u32` @@ -56,7 +56,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:40:16 + --> $DIR/numeric-suffix-i64.rs:29:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `i64`, found `u16` @@ -75,7 +75,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:44:16 + --> $DIR/numeric-suffix-i64.rs:33:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `i64`, found `u8` @@ -94,7 +94,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:48:16 + --> $DIR/numeric-suffix-i64.rs:37:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `i64`, found `isize` @@ -113,7 +113,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:53:16 + --> $DIR/numeric-suffix-i64.rs:42:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `i64`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:57:16 + --> $DIR/numeric-suffix-i64.rs:46:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `i64`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:61:16 + --> $DIR/numeric-suffix-i64.rs:50:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `i64`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:65:16 + --> $DIR/numeric-suffix-i64.rs:54:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `i64`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42i64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-i64.rs:69:16 + --> $DIR/numeric-suffix-i64.rs:58:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `i64`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed index 23e7cf780e9a..f24fce3f1d67 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_isize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs index 5d6fd4d932ac..fdf86895ff23 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr index 8365350f2bfe..99561b19021a 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:28:18 + --> $DIR/numeric-suffix-isize.rs:17:18 | LL | foo::(42_usize); | ------------ ^^^^^^^^ expected `isize`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:32:18 + --> $DIR/numeric-suffix-isize.rs:21:18 | LL | foo::(42_u64); | ------------ ^^^^^^ expected `isize`, found `u64` @@ -37,7 +37,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:36:18 + --> $DIR/numeric-suffix-isize.rs:25:18 | LL | foo::(42_u32); | ------------ ^^^^^^ expected `isize`, found `u32` @@ -56,7 +56,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:40:18 + --> $DIR/numeric-suffix-isize.rs:29:18 | LL | foo::(42_u16); | ------------ ^^^^^^ expected `isize`, found `u16` @@ -75,7 +75,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:44:18 + --> $DIR/numeric-suffix-isize.rs:33:18 | LL | foo::(42_u8); | ------------ ^^^^^ expected `isize`, found `u8` @@ -94,7 +94,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:49:18 + --> $DIR/numeric-suffix-isize.rs:38:18 | LL | foo::(42_i64); | ------------ ^^^^^^ expected `isize`, found `i64` @@ -113,7 +113,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:53:18 + --> $DIR/numeric-suffix-isize.rs:42:18 | LL | foo::(42_i32); | ------------ ^^^^^^ expected `isize`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:57:18 + --> $DIR/numeric-suffix-isize.rs:46:18 | LL | foo::(42_i16); | ------------ ^^^^^^ expected `isize`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:61:18 + --> $DIR/numeric-suffix-isize.rs:50:18 | LL | foo::(42_i8); | ------------ ^^^^^ expected `isize`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:65:18 + --> $DIR/numeric-suffix-isize.rs:54:18 | LL | foo::(42.0_f64); | ------------ ^^^^^^^^ expected `isize`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42isize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-isize.rs:69:18 + --> $DIR/numeric-suffix-isize.rs:58:18 | LL | foo::(42.0_f32); | ------------ ^^^^^^^^ expected `isize`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed index 2dd7d9aabdb5..eba5d7c1c266 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_u32); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs index 46bbb0331854..d127353e9754 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr index 610e6ece2769..95e913595e5e 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:28:16 + --> $DIR/numeric-suffix-u32.rs:17:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `u32`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:32:16 + --> $DIR/numeric-suffix-u32.rs:21:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `u32`, found `u64` @@ -37,7 +37,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:37:16 + --> $DIR/numeric-suffix-u32.rs:26:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `u32`, found `u16` @@ -56,7 +56,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:41:16 + --> $DIR/numeric-suffix-u32.rs:30:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `u32`, found `u8` @@ -75,7 +75,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:45:16 + --> $DIR/numeric-suffix-u32.rs:34:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `u32`, found `isize` @@ -94,7 +94,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:49:16 + --> $DIR/numeric-suffix-u32.rs:38:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `u32`, found `i64` @@ -113,7 +113,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:53:16 + --> $DIR/numeric-suffix-u32.rs:42:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `u32`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:57:16 + --> $DIR/numeric-suffix-u32.rs:46:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `u32`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:61:16 + --> $DIR/numeric-suffix-u32.rs:50:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `u32`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:65:16 + --> $DIR/numeric-suffix-u32.rs:54:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `u32`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42u32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u32.rs:69:16 + --> $DIR/numeric-suffix-u32.rs:58:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `u32`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed index 2dea195f0981..c8344211d3d0 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_u64); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs index 6fca089b07d4..f9b35efbc4be 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr index 112dddccd6f4..0c92b4137614 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:28:16 + --> $DIR/numeric-suffix-u64.rs:17:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `u64`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:33:16 + --> $DIR/numeric-suffix-u64.rs:22:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `u64`, found `u32` @@ -37,7 +37,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:37:16 + --> $DIR/numeric-suffix-u64.rs:26:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `u64`, found `u16` @@ -56,7 +56,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:41:16 + --> $DIR/numeric-suffix-u64.rs:30:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `u64`, found `u8` @@ -75,7 +75,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:45:16 + --> $DIR/numeric-suffix-u64.rs:34:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `u64`, found `isize` @@ -94,7 +94,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:49:16 + --> $DIR/numeric-suffix-u64.rs:38:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `u64`, found `i64` @@ -113,7 +113,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:53:16 + --> $DIR/numeric-suffix-u64.rs:42:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `u64`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:57:16 + --> $DIR/numeric-suffix-u64.rs:46:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `u64`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:61:16 + --> $DIR/numeric-suffix-u64.rs:50:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `u64`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:65:16 + --> $DIR/numeric-suffix-u64.rs:54:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `u64`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42u64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-u64.rs:69:16 + --> $DIR/numeric-suffix-u64.rs:58:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `u64`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed index 63422c305d35..4d5176fe7245 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs index 4d20e4fc8431..118d8ca219ec 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs @@ -12,17 +12,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr index e7d6a04f18ef..86181d6714f5 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:29:18 + --> $DIR/numeric-suffix-usize.rs:18:18 | LL | foo::(42_u64); | ------------ ^^^^^^ expected `usize`, found `u64` @@ -18,7 +18,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:33:18 + --> $DIR/numeric-suffix-usize.rs:22:18 | LL | foo::(42_u32); | ------------ ^^^^^^ expected `usize`, found `u32` @@ -37,7 +37,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:37:18 + --> $DIR/numeric-suffix-usize.rs:26:18 | LL | foo::(42_u16); | ------------ ^^^^^^ expected `usize`, found `u16` @@ -56,7 +56,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:41:18 + --> $DIR/numeric-suffix-usize.rs:30:18 | LL | foo::(42_u8); | ------------ ^^^^^ expected `usize`, found `u8` @@ -75,7 +75,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:45:18 + --> $DIR/numeric-suffix-usize.rs:34:18 | LL | foo::(42_isize); | ------------ ^^^^^^^^ expected `usize`, found `isize` @@ -94,7 +94,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:49:18 + --> $DIR/numeric-suffix-usize.rs:38:18 | LL | foo::(42_i64); | ------------ ^^^^^^ expected `usize`, found `i64` @@ -113,7 +113,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:53:18 + --> $DIR/numeric-suffix-usize.rs:42:18 | LL | foo::(42_i32); | ------------ ^^^^^^ expected `usize`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:57:18 + --> $DIR/numeric-suffix-usize.rs:46:18 | LL | foo::(42_i16); | ------------ ^^^^^^ expected `usize`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:61:18 + --> $DIR/numeric-suffix-usize.rs:50:18 | LL | foo::(42_i8); | ------------ ^^^^^ expected `usize`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:65:18 + --> $DIR/numeric-suffix-usize.rs:54:18 | LL | foo::(42.0_f64); | ------------ ^^^^^^^^ expected `usize`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42usize); | error[E0308]: mismatched types - --> $DIR/numeric-suffix-usize.rs:69:18 + --> $DIR/numeric-suffix-usize.rs:58:18 | LL | foo::(42.0_f32); | ------------ ^^^^^^^^ expected `usize`, found `f32` diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed index 270afb639575..b20b594dc2c3 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed @@ -69,75 +69,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE - fn main() { foo::(42_u16); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix.rs index 05be58e335bc..9272902f5190 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix.rs +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.rs @@ -69,75 +69,6 @@ fn foo(_x: N) {} //~| NOTE function defined here //~| NOTE function defined here //~| NOTE function defined here -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE -//~| NOTE - fn main() { foo::(42_usize); diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr index d26639a76f0f..cae1268beec0 100644 --- a/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr +++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:143:16 + --> $DIR/numeric-suffix.rs:74:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `u16`, found `usize` @@ -18,7 +18,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:147:16 + --> $DIR/numeric-suffix.rs:78:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `u16`, found `u64` @@ -37,7 +37,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:151:16 + --> $DIR/numeric-suffix.rs:82:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `u16`, found `u32` @@ -56,7 +56,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:156:16 + --> $DIR/numeric-suffix.rs:87:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `u16`, found `u8` @@ -75,7 +75,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:160:16 + --> $DIR/numeric-suffix.rs:91:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `u16`, found `isize` @@ -94,7 +94,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:164:16 + --> $DIR/numeric-suffix.rs:95:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `u16`, found `i64` @@ -113,7 +113,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:168:16 + --> $DIR/numeric-suffix.rs:99:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `u16`, found `i32` @@ -132,7 +132,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:172:16 + --> $DIR/numeric-suffix.rs:103:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `u16`, found `i16` @@ -151,7 +151,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:176:16 + --> $DIR/numeric-suffix.rs:107:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `u16`, found `i8` @@ -170,7 +170,7 @@ LL + foo::(42_u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:180:16 + --> $DIR/numeric-suffix.rs:111:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `u16`, found `f64` @@ -189,7 +189,7 @@ LL + foo::(42u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:184:16 + --> $DIR/numeric-suffix.rs:115:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `u16`, found `f32` @@ -208,7 +208,7 @@ LL + foo::(42u16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:189:16 + --> $DIR/numeric-suffix.rs:120:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `i16`, found `usize` @@ -227,7 +227,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:193:16 + --> $DIR/numeric-suffix.rs:124:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `i16`, found `u64` @@ -246,7 +246,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:197:16 + --> $DIR/numeric-suffix.rs:128:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `i16`, found `u32` @@ -265,7 +265,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:201:16 + --> $DIR/numeric-suffix.rs:132:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `i16`, found `u16` @@ -284,7 +284,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:205:16 + --> $DIR/numeric-suffix.rs:136:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `i16`, found `u8` @@ -303,7 +303,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:209:16 + --> $DIR/numeric-suffix.rs:140:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `i16`, found `isize` @@ -322,7 +322,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:213:16 + --> $DIR/numeric-suffix.rs:144:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `i16`, found `i64` @@ -341,7 +341,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:217:16 + --> $DIR/numeric-suffix.rs:148:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `i16`, found `i32` @@ -360,7 +360,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:222:16 + --> $DIR/numeric-suffix.rs:153:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `i16`, found `i8` @@ -379,7 +379,7 @@ LL + foo::(42_i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:226:16 + --> $DIR/numeric-suffix.rs:157:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `i16`, found `f64` @@ -398,7 +398,7 @@ LL + foo::(42i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:230:16 + --> $DIR/numeric-suffix.rs:161:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `i16`, found `f32` @@ -417,7 +417,7 @@ LL + foo::(42i16); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:235:15 + --> $DIR/numeric-suffix.rs:166:15 | LL | foo::(42_usize); | --------- ^^^^^^^^ expected `u8`, found `usize` @@ -436,7 +436,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:239:15 + --> $DIR/numeric-suffix.rs:170:15 | LL | foo::(42_u64); | --------- ^^^^^^ expected `u8`, found `u64` @@ -455,7 +455,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:243:15 + --> $DIR/numeric-suffix.rs:174:15 | LL | foo::(42_u32); | --------- ^^^^^^ expected `u8`, found `u32` @@ -474,7 +474,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:247:15 + --> $DIR/numeric-suffix.rs:178:15 | LL | foo::(42_u16); | --------- ^^^^^^ expected `u8`, found `u16` @@ -493,7 +493,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:252:15 + --> $DIR/numeric-suffix.rs:183:15 | LL | foo::(42_isize); | --------- ^^^^^^^^ expected `u8`, found `isize` @@ -512,7 +512,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:256:15 + --> $DIR/numeric-suffix.rs:187:15 | LL | foo::(42_i64); | --------- ^^^^^^ expected `u8`, found `i64` @@ -531,7 +531,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:260:15 + --> $DIR/numeric-suffix.rs:191:15 | LL | foo::(42_i32); | --------- ^^^^^^ expected `u8`, found `i32` @@ -550,7 +550,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:264:15 + --> $DIR/numeric-suffix.rs:195:15 | LL | foo::(42_i16); | --------- ^^^^^^ expected `u8`, found `i16` @@ -569,7 +569,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:268:15 + --> $DIR/numeric-suffix.rs:199:15 | LL | foo::(42_i8); | --------- ^^^^^ expected `u8`, found `i8` @@ -588,7 +588,7 @@ LL + foo::(42_u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:272:15 + --> $DIR/numeric-suffix.rs:203:15 | LL | foo::(42.0_f64); | --------- ^^^^^^^^ expected `u8`, found `f64` @@ -607,7 +607,7 @@ LL + foo::(42u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:276:15 + --> $DIR/numeric-suffix.rs:207:15 | LL | foo::(42.0_f32); | --------- ^^^^^^^^ expected `u8`, found `f32` @@ -626,7 +626,7 @@ LL + foo::(42u8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:281:15 + --> $DIR/numeric-suffix.rs:212:15 | LL | foo::(42_usize); | --------- ^^^^^^^^ expected `i8`, found `usize` @@ -645,7 +645,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:285:15 + --> $DIR/numeric-suffix.rs:216:15 | LL | foo::(42_u64); | --------- ^^^^^^ expected `i8`, found `u64` @@ -664,7 +664,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:289:15 + --> $DIR/numeric-suffix.rs:220:15 | LL | foo::(42_u32); | --------- ^^^^^^ expected `i8`, found `u32` @@ -683,7 +683,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:293:15 + --> $DIR/numeric-suffix.rs:224:15 | LL | foo::(42_u16); | --------- ^^^^^^ expected `i8`, found `u16` @@ -702,7 +702,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:297:15 + --> $DIR/numeric-suffix.rs:228:15 | LL | foo::(42_u8); | --------- ^^^^^ expected `i8`, found `u8` @@ -721,7 +721,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:301:15 + --> $DIR/numeric-suffix.rs:232:15 | LL | foo::(42_isize); | --------- ^^^^^^^^ expected `i8`, found `isize` @@ -740,7 +740,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:305:15 + --> $DIR/numeric-suffix.rs:236:15 | LL | foo::(42_i64); | --------- ^^^^^^ expected `i8`, found `i64` @@ -759,7 +759,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:309:15 + --> $DIR/numeric-suffix.rs:240:15 | LL | foo::(42_i32); | --------- ^^^^^^ expected `i8`, found `i32` @@ -778,7 +778,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:313:15 + --> $DIR/numeric-suffix.rs:244:15 | LL | foo::(42_i16); | --------- ^^^^^^ expected `i8`, found `i16` @@ -797,7 +797,7 @@ LL + foo::(42_i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:318:15 + --> $DIR/numeric-suffix.rs:249:15 | LL | foo::(42.0_f64); | --------- ^^^^^^^^ expected `i8`, found `f64` @@ -816,7 +816,7 @@ LL + foo::(42i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:322:15 + --> $DIR/numeric-suffix.rs:253:15 | LL | foo::(42.0_f32); | --------- ^^^^^^^^ expected `i8`, found `f32` @@ -835,7 +835,7 @@ LL + foo::(42i8); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:327:16 + --> $DIR/numeric-suffix.rs:258:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `f64`, found `usize` @@ -854,7 +854,7 @@ LL + foo::(42_f64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:331:16 + --> $DIR/numeric-suffix.rs:262:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `f64`, found `u64` @@ -873,7 +873,7 @@ LL + foo::(42_f64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:335:16 + --> $DIR/numeric-suffix.rs:266:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `f64`, found `u32` @@ -891,7 +891,7 @@ LL | foo::(42_u32.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:339:16 + --> $DIR/numeric-suffix.rs:270:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `f64`, found `u16` @@ -909,7 +909,7 @@ LL | foo::(42_u16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:343:16 + --> $DIR/numeric-suffix.rs:274:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `f64`, found `u8` @@ -927,7 +927,7 @@ LL | foo::(42_u8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:347:16 + --> $DIR/numeric-suffix.rs:278:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `f64`, found `isize` @@ -946,7 +946,7 @@ LL + foo::(42_f64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:351:16 + --> $DIR/numeric-suffix.rs:282:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `f64`, found `i64` @@ -965,7 +965,7 @@ LL + foo::(42_f64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:355:16 + --> $DIR/numeric-suffix.rs:286:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `f64`, found `i32` @@ -983,7 +983,7 @@ LL | foo::(42_i32.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:359:16 + --> $DIR/numeric-suffix.rs:290:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `f64`, found `i16` @@ -1001,7 +1001,7 @@ LL | foo::(42_i16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:363:16 + --> $DIR/numeric-suffix.rs:294:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `f64`, found `i8` @@ -1019,7 +1019,7 @@ LL | foo::(42_i8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:368:16 + --> $DIR/numeric-suffix.rs:299:16 | LL | foo::(42.0_f32); | ---------- ^^^^^^^^ expected `f64`, found `f32` @@ -1038,7 +1038,7 @@ LL + foo::(42.0_f64); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:373:16 + --> $DIR/numeric-suffix.rs:304:16 | LL | foo::(42_usize); | ---------- ^^^^^^^^ expected `f32`, found `usize` @@ -1057,7 +1057,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:377:16 + --> $DIR/numeric-suffix.rs:308:16 | LL | foo::(42_u64); | ---------- ^^^^^^ expected `f32`, found `u64` @@ -1076,7 +1076,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:381:16 + --> $DIR/numeric-suffix.rs:312:16 | LL | foo::(42_u32); | ---------- ^^^^^^ expected `f32`, found `u32` @@ -1095,7 +1095,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:385:16 + --> $DIR/numeric-suffix.rs:316:16 | LL | foo::(42_u16); | ---------- ^^^^^^ expected `f32`, found `u16` @@ -1113,7 +1113,7 @@ LL | foo::(42_u16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:389:16 + --> $DIR/numeric-suffix.rs:320:16 | LL | foo::(42_u8); | ---------- ^^^^^ expected `f32`, found `u8` @@ -1131,7 +1131,7 @@ LL | foo::(42_u8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:393:16 + --> $DIR/numeric-suffix.rs:324:16 | LL | foo::(42_isize); | ---------- ^^^^^^^^ expected `f32`, found `isize` @@ -1150,7 +1150,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:397:16 + --> $DIR/numeric-suffix.rs:328:16 | LL | foo::(42_i64); | ---------- ^^^^^^ expected `f32`, found `i64` @@ -1169,7 +1169,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:401:16 + --> $DIR/numeric-suffix.rs:332:16 | LL | foo::(42_i32); | ---------- ^^^^^^ expected `f32`, found `i32` @@ -1188,7 +1188,7 @@ LL + foo::(42_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:405:16 + --> $DIR/numeric-suffix.rs:336:16 | LL | foo::(42_i16); | ---------- ^^^^^^ expected `f32`, found `i16` @@ -1206,7 +1206,7 @@ LL | foo::(42_i16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:409:16 + --> $DIR/numeric-suffix.rs:340:16 | LL | foo::(42_i8); | ---------- ^^^^^ expected `f32`, found `i8` @@ -1224,7 +1224,7 @@ LL | foo::(42_i8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:413:16 + --> $DIR/numeric-suffix.rs:344:16 | LL | foo::(42.0_f64); | ---------- ^^^^^^^^ expected `f32`, found `f64` @@ -1243,7 +1243,7 @@ LL + foo::(42.0_f32); | error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:419:16 + --> $DIR/numeric-suffix.rs:350:16 | LL | foo::(42_u8 as u16); | ---------- ^^^^^^^^^^^^ expected `u32`, found `u16` @@ -1261,7 +1261,7 @@ LL | foo::((42_u8 as u16).into()); | + ++++++++ error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:423:16 + --> $DIR/numeric-suffix.rs:354:16 | LL | foo::(-42_i8); | ---------- ^^^^^^ expected `i32`, found `i8` diff --git a/tests/ui/parser/fn-arg-doc-comment.rs b/tests/ui/parser/fn-arg-doc-comment.rs index 21d753ad0372..57a4d15fa256 100644 --- a/tests/ui/parser/fn-arg-doc-comment.rs +++ b/tests/ui/parser/fn-arg-doc-comment.rs @@ -2,12 +2,10 @@ pub fn f( //~ NOTE function defined here /// Comment //~^ ERROR documentation comments cannot be applied to function parameters //~| NOTE doc comments are not allowed here - //~| NOTE id: u8, /// Other //~^ ERROR documentation comments cannot be applied to function parameters //~| NOTE doc comments are not allowed here - //~| NOTE a: u8, ) {} @@ -15,7 +13,6 @@ fn bar(id: #[allow(dead_code)] i32) {} //~^ ERROR attributes cannot be applied to a function parameter's type //~| NOTE attributes are not allowed here //~| NOTE function defined here -//~| NOTE fn main() { // verify that the parser recovered and properly typechecked the args diff --git a/tests/ui/parser/fn-arg-doc-comment.stderr b/tests/ui/parser/fn-arg-doc-comment.stderr index 1891c7089034..84c8bb3c2d09 100644 --- a/tests/ui/parser/fn-arg-doc-comment.stderr +++ b/tests/ui/parser/fn-arg-doc-comment.stderr @@ -1,5 +1,5 @@ error: attributes cannot be applied to a function parameter's type - --> $DIR/fn-arg-doc-comment.rs:14:12 + --> $DIR/fn-arg-doc-comment.rs:12:12 | LL | fn bar(id: #[allow(dead_code)] i32) {} | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here @@ -11,13 +11,13 @@ LL | /// Comment | ^^^^^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/fn-arg-doc-comment.rs:7:5 + --> $DIR/fn-arg-doc-comment.rs:6:5 | LL | /// Other | ^^^^^^^^^ doc comments are not allowed here error[E0308]: arguments to this function are incorrect - --> $DIR/fn-arg-doc-comment.rs:22:5 + --> $DIR/fn-arg-doc-comment.rs:19:5 | LL | f("", ""); | ^ -- -- expected `u8`, found `&str` @@ -39,7 +39,7 @@ LL | | a: u8, | |_________- error[E0308]: mismatched types - --> $DIR/fn-arg-doc-comment.rs:26:9 + --> $DIR/fn-arg-doc-comment.rs:23:9 | LL | bar(""); | --- ^^ expected `i32`, found `&str` @@ -47,7 +47,7 @@ LL | bar(""); | arguments to this function are incorrect | note: function defined here - --> $DIR/fn-arg-doc-comment.rs:14:4 + --> $DIR/fn-arg-doc-comment.rs:12:4 | LL | fn bar(id: #[allow(dead_code)] i32) {} | ^^^ --------------------------- diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs index c137e1363359..e6235b1e8923 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs +++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs @@ -10,6 +10,5 @@ const async const fn test() {} //~| ERROR functions cannot be both `const` and `async` //~| NOTE `const` because of this //~| NOTE `async` because of this -//~| NOTE fn main() {} diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs index 49a49d337c47..40f993eafbb1 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs +++ b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs @@ -15,6 +15,5 @@ async unsafe const fn test() {} //~| ERROR functions cannot be both `const` and `async` //~| NOTE `const` because of this //~| NOTE `async` because of this -//~| NOTE fn main() {} diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs index cbfcf0eafd49..6c5a331b4b56 100644 --- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs +++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs @@ -1,6 +1,5 @@ enum A {} //~^ NOTE `A` defined here - //~| NOTE fn f(a: &A) { match a {} diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr index c37a9a515790..67ee38eed60c 100644 --- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr +++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `&A` is non-empty - --> $DIR/issue-78123-non-exhaustive-reference.rs:6:11 + --> $DIR/issue-78123-non-exhaustive-reference.rs:5:11 | LL | match a {} | ^ diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index 258374f299e2..504e6aa6db08 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -3,7 +3,6 @@ struct S(Option<(A, B)>); impl S { fn infer(&self, a: A, b: B) {} //~^ NOTE method defined here - //~| NOTE } fn main() { diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index adfb0cebf26e..8630f75d1190 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -1,5 +1,5 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied - --> $DIR/point-at-inference-4.rs:11:7 + --> $DIR/point-at-inference-4.rs:10:7 | LL | s.infer(0i32); | ^^^^^------ argument #2 is missing @@ -15,7 +15,7 @@ LL | s.infer(0i32, /* b */); | +++++++++ error[E0308]: mismatched types - --> $DIR/point-at-inference-4.rs:18:24 + --> $DIR/point-at-inference-4.rs:17:24 | LL | s.infer(0i32); | - ---- this argument has type `i32`... From a82b7a63b7843b703d9ad41e52a215aaa2fa86ef Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Sun, 4 May 2025 01:24:39 +0700 Subject: [PATCH 122/262] Async drop source info fix for proxy-drop-coroutine - fixes crash at debug info generation --- compiler/rustc_middle/src/ty/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2f4c03f0953d..b13e33718b29 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1929,13 +1929,17 @@ impl<'tcx> TyCtxt<'tcx> { if arg_cor_ty.is_coroutine() { let span = self.def_span(def_id); let source_info = SourceInfo::outermost(span); + // Even minimal, empty coroutine has 3 states (RESERVED_VARIANTS), + // so variant_fields and variant_source_info should have 3 elements. let variant_fields: IndexVec> = iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect(); + let variant_source_info: IndexVec = + iter::repeat(source_info).take(CoroutineArgs::RESERVED_VARIANTS).collect(); let proxy_layout = CoroutineLayout { field_tys: [].into(), field_names: [].into(), variant_fields, - variant_source_info: [source_info].into(), + variant_source_info, storage_conflicts: BitMatrix::new(0, 0), }; return Some(self.arena.alloc(proxy_layout)); From 4ba683ee529ed87cc52d4983492dbf89b495ca0f Mon Sep 17 00:00:00 2001 From: Skgland Date: Sat, 3 May 2025 22:36:17 +0200 Subject: [PATCH 123/262] add a test for issue rust-lang/rust#81317 --- .../type-inference/regression-issue-81317.rs | 40 +++++++++++++++++++ .../regression-issue-81317.stderr | 17 ++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/ui/type-inference/regression-issue-81317.rs create mode 100644 tests/ui/type-inference/regression-issue-81317.stderr diff --git a/tests/ui/type-inference/regression-issue-81317.rs b/tests/ui/type-inference/regression-issue-81317.rs new file mode 100644 index 000000000000..50deb013d4b1 --- /dev/null +++ b/tests/ui/type-inference/regression-issue-81317.rs @@ -0,0 +1,40 @@ +// Regression test for #81317: type can no longer be infered as of 1.49 +//@ check-fail + +use std::ops::BitXor; + +pub struct S; + +pub trait P { + type I: Into + Into; +} + +pub fn decrypt_portion(index: T::I) { + let iv = S ^ index.into(); + //~^ ERROR type annotations needed + &iv.to_bytes_be(); +} + +impl S { + fn to_bytes_be(&self) -> &[u8] { + &[] + } +} + +impl BitXor for S { + type Output = S; + + fn bitxor(self, _rhs: Self) -> Self::Output { + S + } +} + +impl<'a> BitXor<&'a S> for S { + type Output = S; + + fn bitxor(self, _rhs: &'a S) -> Self::Output { + S + } +} + +fn main() {} diff --git a/tests/ui/type-inference/regression-issue-81317.stderr b/tests/ui/type-inference/regression-issue-81317.stderr new file mode 100644 index 000000000000..d018a2c48545 --- /dev/null +++ b/tests/ui/type-inference/regression-issue-81317.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed + --> $DIR/regression-issue-81317.rs:13:9 + | +LL | let iv = S ^ index.into(); + | ^^ +LL | +LL | &iv.to_bytes_be(); + | -- type must be known at this point + | +help: consider giving `iv` an explicit type + | +LL | let iv: /* Type */ = S ^ index.into(); + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From d0216b5386016c1cc3b2d1125c6716cfe19a218e Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 3 May 2025 03:01:24 +0000 Subject: [PATCH 124/262] `fn check_opaque_type_parameter_valid` defer error --- .../src/region_infer/opaque_types.rs | 4 +- compiler/rustc_hir_typeck/src/writeback.rs | 9 +- .../rustc_trait_selection/src/opaque_types.rs | 83 ++++++++++++------- 3 files changed, 61 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 550c57338d30..25cbd579ea1c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -267,13 +267,13 @@ impl<'tcx> InferCtxt<'tcx> { return Ty::new_error(self.tcx, e); } - if let Err(guar) = check_opaque_type_parameter_valid( + if let Err(err) = check_opaque_type_parameter_valid( self, opaque_type_key, instantiated_ty.span, DefiningScopeKind::MirBorrowck, ) { - return Ty::new_error(self.tcx, guar); + return Ty::new_error(self.tcx, err.report(self)); } let definition_ty = instantiated_ty diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 4a171a08ef72..8e7ce83044cd 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -555,15 +555,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - if let Err(guar) = check_opaque_type_parameter_valid( + if let Err(err) = check_opaque_type_parameter_valid( &self.fcx, opaque_type_key, hidden_type.span, DefiningScopeKind::HirTypeck, ) { - self.typeck_results - .concrete_opaque_types - .insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar)); + self.typeck_results.concrete_opaque_types.insert( + opaque_type_key.def_id, + ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)), + ); } let hidden_type = hidden_type.remap_generic_params_to_declaration_params( diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index cce67b066dde..332204a0c5f0 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam; use crate::regions::OutlivesEnvironmentBuildExt; use crate::traits::ObligationCtxt; +pub enum InvalidOpaqueTypeArgs<'tcx> { + AlreadyReported(ErrorGuaranteed), + NotAParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_index: usize, span: Span }, + DuplicateParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_indices: Vec, span: Span }, +} +impl From for InvalidOpaqueTypeArgs<'_> { + fn from(guar: ErrorGuaranteed) -> Self { + InvalidOpaqueTypeArgs::AlreadyReported(guar) + } +} +impl<'tcx> InvalidOpaqueTypeArgs<'tcx> { + pub fn report(self, infcx: &InferCtxt<'tcx>) -> ErrorGuaranteed { + let tcx = infcx.tcx; + match self { + InvalidOpaqueTypeArgs::AlreadyReported(guar) => guar, + InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index, span } => { + let opaque_generics = tcx.generics_of(opaque_type_key.def_id); + let opaque_param = opaque_generics.param_at(param_index, tcx); + let kind = opaque_param.kind.descr(); + infcx.dcx().emit_err(NonGenericOpaqueTypeParam { + arg: opaque_type_key.args[param_index], + kind, + span, + param_span: tcx.def_span(opaque_param.def_id), + }) + } + InvalidOpaqueTypeArgs::DuplicateParam { opaque_type_key, param_indices, span } => { + let opaque_generics = tcx.generics_of(opaque_type_key.def_id); + let descr = opaque_generics.param_at(param_indices[0], tcx).kind.descr(); + let spans: Vec<_> = param_indices + .into_iter() + .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) + .collect(); + infcx + .dcx() + .struct_span_err(span, "non-defining opaque type use in defining scope") + .with_span_note(spans, format!("{descr} used multiple times")) + .emit() + } + } + } +} + /// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter]. /// /// [rustc-dev-guide chapter]: @@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>( opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, defining_scope_kind: DefiningScopeKind, -) -> Result<(), ErrorGuaranteed> { +) -> Result<(), InvalidOpaqueTypeArgs<'tcx>> { let tcx = infcx.tcx; - let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); // Avoid duplicate errors in case the opaque has already been malformed in // HIR typeck. if let DefiningScopeKind::MirBorrowck = defining_scope_kind { - if let Err(guar) = infcx + infcx .tcx .type_of_opaque_hir_typeck(opaque_type_key.def_id) .instantiate_identity() - .error_reported() - { - return Err(guar); - } + .error_reported()?; } for (i, arg) in opaque_type_key.iter_captured_args(tcx) { @@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>( } } else { // Prevent `fn foo() -> Foo` from being defining. - let opaque_param = opaque_generics.param_at(i, tcx); - let kind = opaque_param.kind.descr(); - opaque_env.param_is_error(i)?; - - return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { - arg, - kind, - span, - param_span: tcx.def_span(opaque_param.def_id), - })); + return Err(InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index: i, span }); } } - for (_, indices) in seen_params { - if indices.len() > 1 { - let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); - let spans: Vec<_> = indices - .into_iter() - .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) - .collect(); - return Err(infcx - .dcx() - .struct_span_err(span, "non-defining opaque type use in defining scope") - .with_span_note(spans, format!("{descr} used multiple times")) - .emit()); + for (_, param_indices) in seen_params { + if param_indices.len() > 1 { + return Err(InvalidOpaqueTypeArgs::DuplicateParam { + opaque_type_key, + param_indices, + span, + }); } } From 78823fea217056f00d37943f837ccc715462b110 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 4 May 2025 00:25:46 +0000 Subject: [PATCH 125/262] cargo update compiler & tools dependencies: Locking 36 packages to latest compatible versions Updating addr2line v0.21.0 -> v0.24.2 Updating anyhow v1.0.97 -> v1.0.98 Updating askama v0.13.0 -> v0.13.1 (available: v0.14.0) Updating askama_derive v0.13.0 -> v0.13.1 Updating backtrace v0.3.71 -> v0.3.74 Updating blake3 v1.8.1 -> v1.8.2 Updating chrono v0.4.40 -> v0.4.41 Updating clap v4.5.36 -> v4.5.37 Updating clap_builder v4.5.36 -> v4.5.37 Updating color-eyre v0.6.3 -> v0.6.4 Updating color-spantrace v0.2.1 -> v0.2.2 Updating derive-where v1.2.7 -> v1.4.0 Updating getrandom v0.2.15 -> v0.2.16 Removing gimli v0.28.1 Updating hashbrown v0.15.2 -> v0.15.3 Updating jiff v0.2.6 -> v0.2.12 Updating jiff-static v0.2.6 -> v0.2.12 Updating libm v0.2.11 -> v0.2.13 Removing object v0.32.2 Updating openssl-sys v0.9.107 -> v0.9.108 Adding owo-colors v4.2.0 Updating proc-macro2 v1.0.94 -> v1.0.95 Updating psm v0.1.25 -> v0.1.26 Updating rand v0.9.0 -> v0.9.1 Updating redox_syscall v0.5.11 -> v0.5.12 Updating rustix v1.0.5 -> v1.0.7 Updating sha2 v0.10.8 -> v0.10.9 Updating stacker v0.1.20 -> v0.1.21 Updating syn v2.0.100 -> v2.0.101 Updating synstructure v0.13.1 -> v0.13.2 Updating toml_datetime v0.6.8 -> v0.6.9 Adding windows v0.61.1 Adding windows-collections v0.2.0 Adding windows-future v0.2.0 Adding windows-numerics v0.2.0 Updating winnow v0.7.6 -> v0.7.9 Updating zerocopy v0.8.24 -> v0.8.25 Updating zerocopy-derive v0.8.24 -> v0.8.25 note: pass `--verbose` to see 33 unchanged dependencies behind latest library dependencies: Locking 2 packages to latest compatible versions Removing allocator-api2 v0.2.21 Updating hashbrown v0.15.2 -> v0.15.3 Removing proc-macro2 v1.0.94 Removing quote v1.0.40 Updating rand v0.9.0 -> v0.9.1 Removing syn v2.0.100 Removing unicode-ident v1.0.18 Removing zerocopy v0.8.24 Removing zerocopy-derive v0.8.24 note: pass `--verbose` to see 3 unchanged dependencies behind latest rustbook dependencies: Locking 31 packages to latest compatible versions Updating ammonia v4.0.0 -> v4.1.0 Updating anyhow v1.0.97 -> v1.0.98 Updating cc v1.2.19 -> v1.2.21 Updating chrono v0.4.40 -> v0.4.41 Updating clap v4.5.36 -> v4.5.37 Updating clap_builder v4.5.36 -> v4.5.37 Updating clap_complete v4.5.47 -> v4.5.48 Adding cssparser v0.35.0 Adding cssparser-macros v0.6.1 Adding dtoa v1.0.10 Adding dtoa-short v0.3.5 Updating hashbrown v0.15.2 -> v0.15.3 Updating html5ever v0.27.0 -> v0.31.0 Updating jiff v0.2.6 -> v0.2.12 Updating jiff-static v0.2.6 -> v0.2.12 Updating libc v0.2.171 -> v0.2.172 Updating markup5ever v0.12.1 -> v0.16.1 Adding match_token v0.1.0 Adding phf_macros v0.11.3 Updating proc-macro2 v1.0.94 -> v1.0.95 Updating redox_syscall v0.5.11 -> v0.5.12 Updating rustix v1.0.5 -> v1.0.7 Updating sha2 v0.10.8 -> v0.10.9 Updating syn v2.0.100 -> v2.0.101 Updating synstructure v0.13.1 -> v0.13.2 Updating toml v0.8.20 -> v0.8.22 Updating toml_datetime v0.6.8 -> v0.6.9 Updating toml_edit v0.22.24 -> v0.22.26 Adding toml_write v0.1.1 Adding web_atoms v0.1.1 Updating winnow v0.7.6 -> v0.7.9 --- Cargo.lock | 324 +++++++++++++++++++--------------- library/Cargo.lock | 71 +------- src/tools/rustbook/Cargo.lock | 187 ++++++++++++++------ 3 files changed, 314 insertions(+), 268 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4097c0cc0a91..967da170476e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 4 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli 0.28.1", + "gimli", ] [[package]] @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "ar_archive_writer" @@ -168,7 +168,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4" dependencies = [ - "object 0.36.7", + "object", ] [[package]] @@ -185,9 +185,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "askama" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a4e46abb203e00ef226442d452769233142bbfdd79c3941e84c8e61c4112543" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" dependencies = [ "askama_derive", "itoa", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54398906821fd32c728135f7b351f0c7494ab95ae421d41b6f5a020e158f28a6" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" dependencies = [ "askama_parser", "basic-toml", @@ -210,7 +210,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "serde_derive", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -222,7 +222,7 @@ dependencies = [ "memchr", "serde", "serde_derive", - "winnow 0.7.6", + "winnow 0.7.9", ] [[package]] @@ -233,17 +233,17 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", - "object 0.32.2", + "miniz_oxide 0.8.8", + "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -278,9 +278,9 @@ checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "blake3" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ "arrayref", "arrayvec", @@ -449,9 +449,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -493,9 +493,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -513,9 +513,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -532,7 +532,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -564,7 +564,7 @@ dependencies = [ "rustc_tools_util 0.4.2", "serde", "serde_json", - "syn 2.0.100", + "syn 2.0.101", "tempfile", "termize", "tokio", @@ -650,16 +650,16 @@ dependencies = [ [[package]] name = "color-eyre" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +checksum = "e6e1761c0e16f8883bbbb8ce5990867f4f06bf11a0253da6495a04ce4b6ef0ec" dependencies = [ "backtrace", "color-spantrace", "eyre", "indenter", "once_cell", - "owo-colors", + "owo-colors 4.2.0", "tracing-error", ] @@ -681,17 +681,17 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "color-spantrace" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +checksum = "2ddd8d5bfda1e11a501d0a7303f3bfed9aa632ebdb859be40d0fd70478ed70d5" dependencies = [ "once_cell", - "owo-colors", + "owo-colors 4.2.0", "tracing-core", "tracing-error", ] @@ -744,7 +744,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows", + "windows 0.59.0", ] [[package]] @@ -907,7 +907,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -918,7 +918,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -940,13 +940,13 @@ dependencies = [ [[package]] name = "derive-where" -version = "1.2.7" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" +checksum = "e73f2692d4bd3cac41dca28934a39894200c9fabf49586d77d0e5954af1d7902" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -967,7 +967,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -977,7 +977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -989,7 +989,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1079,7 +1079,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1358,7 +1358,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1431,9 +1431,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -1452,12 +1452,6 @@ dependencies = [ "wasi 0.14.2+wasi-0.2.4", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "gimli" version = "0.31.1" @@ -1499,9 +1493,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -1758,7 +1752,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1916,9 +1910,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" +checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd" dependencies = [ "jiff-static", "log", @@ -1929,13 +1923,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" +checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2073,9 +2067,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" [[package]] name = "libredox" @@ -2199,7 +2193,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2304,7 +2298,7 @@ dependencies = [ "libffi", "libloading", "measureme", - "rand 0.9.0", + "rand 0.9.1", "regex", "rustc_version", "smallvec", @@ -2482,15 +2476,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "object" version = "0.36.7" @@ -2541,9 +2526,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.107" +version = "0.9.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" dependencies = [ "cc", "libc", @@ -2593,6 +2578,12 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "owo-colors" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" + [[package]] name = "pad" version = "0.1.6" @@ -2697,7 +2688,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2814,7 +2805,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9" dependencies = [ - "owo-colors", + "owo-colors 3.5.0", "pad", ] @@ -2826,18 +2817,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58e5423e24c18cc840e1c98370b3993c6649cd1678b4d24318bcf0a083cbe88" +checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" dependencies = [ "cc", ] @@ -2911,13 +2902,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy", ] [[package]] @@ -2946,7 +2936,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -2989,9 +2979,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags", ] @@ -3002,7 +2992,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", "thiserror 1.0.69", ] @@ -3013,7 +3003,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", "thiserror 2.0.12", ] @@ -3099,9 +3089,9 @@ version = "0.2.0" dependencies = [ "bstr", "build_helper", - "gimli 0.31.1", + "gimli", "libc", - "object 0.36.7", + "object", "regex", "serde_json", "similar", @@ -3195,7 +3185,7 @@ name = "rustc_abi" version = "0.0.0" dependencies = [ "bitflags", - "rand 0.9.0", + "rand 0.9.1", "rand_xoshiro", "rustc_data_structures", "rustc_hashes", @@ -3408,11 +3398,11 @@ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ "bitflags", - "gimli 0.31.1", + "gimli", "itertools", "libc", "measureme", - "object 0.36.7", + "object", "rustc-demangle", "rustc_abi", "rustc_ast", @@ -3453,7 +3443,7 @@ dependencies = [ "either", "itertools", "libc", - "object 0.36.7", + "object", "pathdiff", "regex", "rustc_abi", @@ -3485,7 +3475,7 @@ dependencies = [ "thorin-dwp", "tracing", "wasm-encoder 0.219.2", - "windows", + "windows 0.59.0", ] [[package]] @@ -3544,7 +3534,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows", + "windows 0.59.0", ] [[package]] @@ -3607,7 +3597,7 @@ dependencies = [ "serde_json", "shlex", "tracing", - "windows", + "windows 0.59.0", ] [[package]] @@ -3662,7 +3652,7 @@ dependencies = [ "termcolor", "termize", "tracing", - "windows", + "windows 0.59.0", ] [[package]] @@ -3709,7 +3699,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "unic-langid", ] @@ -3821,7 +3811,7 @@ dependencies = [ name = "rustc_incremental" version = "0.0.0" dependencies = [ - "rand 0.9.0", + "rand 0.9.1", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -3855,7 +3845,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4001,7 +3991,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -4387,7 +4377,7 @@ dependencies = [ "bitflags", "getopts", "libc", - "rand 0.9.0", + "rand 0.9.1", "rustc_abi", "rustc_ast", "rustc_data_structures", @@ -4405,7 +4395,7 @@ dependencies = [ "smallvec", "termize", "tracing", - "windows", + "windows 0.59.0", ] [[package]] @@ -4469,7 +4459,7 @@ name = "rustc_target" version = "0.0.0" dependencies = [ "bitflags", - "object 0.36.7", + "object", "rustc_abi", "rustc_data_structures", "rustc_fs_util", @@ -4591,7 +4581,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -4682,7 +4672,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4716,9 +4706,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", @@ -4819,7 +4809,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4856,9 +4846,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -4977,9 +4967,9 @@ dependencies = [ [[package]] name = "stacker" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601f9201feb9b09c00266478bf459952b9ef9a6b94edb2f21eba14ab681a60a9" +checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b" dependencies = [ "cc", "cfg-if", @@ -5065,9 +5055,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -5076,13 +5066,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5094,7 +5084,7 @@ dependencies = [ "libc", "objc2-core-foundation", "objc2-io-kit", - "windows", + "windows 0.61.1", ] [[package]] @@ -5178,7 +5168,7 @@ version = "0.1.0" dependencies = [ "indicatif", "num", - "rand 0.9.0", + "rand 0.9.1", "rand_chacha 0.9.0", "rayon", ] @@ -5215,7 +5205,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5226,7 +5216,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5235,9 +5225,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e9c1e705f82a260173f3eec93f2ff6d7807f23ad5a8cc2e7316a891733ea7a1" dependencies = [ - "gimli 0.31.1", + "gimli", "hashbrown", - "object 0.36.7", + "object", "tracing", ] @@ -5352,9 +5342,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] @@ -5392,7 +5382,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5563,7 +5553,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.100", + "syn 2.0.101", "unic-langid-impl", ] @@ -5779,7 +5769,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-shared", ] @@ -5801,7 +5791,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5979,6 +5969,19 @@ dependencies = [ "windows-targets 0.53.0", ] +[[package]] +name = "windows" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +dependencies = [ + "windows-collections", + "windows-core 0.61.0", + "windows-future", + "windows-link", + "windows-numerics", +] + [[package]] name = "windows-bindgen" version = "0.61.0" @@ -5990,6 +5993,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.0", +] + [[package]] name = "windows-core" version = "0.59.0" @@ -6016,6 +6028,16 @@ dependencies = [ "windows-strings 0.4.0", ] +[[package]] +name = "windows-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +dependencies = [ + "windows-core 0.61.0", + "windows-link", +] + [[package]] name = "windows-implement" version = "0.59.0" @@ -6024,7 +6046,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6035,7 +6057,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6046,7 +6068,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6055,6 +6077,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.0", + "windows-link", +] + [[package]] name = "windows-result" version = "0.3.2" @@ -6305,9 +6337,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.6" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" dependencies = [ "memchr", ] @@ -6428,28 +6460,28 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6469,7 +6501,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -6492,5 +6524,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] diff --git a/library/Cargo.lock b/library/Cargo.lock index f5c04a3bf48c..f766e8bc39c7 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -32,12 +32,6 @@ dependencies = [ "core", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "alloctests" version = "0.0.0" @@ -134,11 +128,10 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ - "allocator-api2", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -221,15 +214,6 @@ dependencies = [ "unwind", ] -[[package]] -name = "proc-macro2" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" -dependencies = [ - "unicode-ident", -] - [[package]] name = "proc_macro" version = "0.0.0" @@ -246,15 +230,6 @@ dependencies = [ "cc", ] -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - [[package]] name = "r-efi" version = "5.2.0" @@ -278,12 +253,11 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_core", - "zerocopy", ] [[package]] @@ -387,17 +361,6 @@ dependencies = [ "rustc-std-workspace-core", ] -[[package]] -name = "syn" -version = "2.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "sysroot" version = "0.0.0" @@ -418,12 +381,6 @@ dependencies = [ "std", ] -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - [[package]] name = "unicode-width" version = "0.1.14" @@ -544,23 +501,3 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index fb584103df5d..81e0f6d572be 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -19,13 +19,13 @@ dependencies = [ [[package]] name = "ammonia" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab99eae5ee58501ab236beb6f20f6ca39be615267b014899c89b2f0bc18a459" +checksum = "3ada2ee439075a3e70b6992fce18ac4e407cd05aea9ca3f75d2c0b0c20bbb364" dependencies = [ + "cssparser", "html5ever", "maplit", - "once_cell", "tendril", "url", ] @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "autocfg" @@ -156,9 +156,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "cc" -version = "1.2.19" +version = "1.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" dependencies = [ "shlex", ] @@ -171,9 +171,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -185,9 +185,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6" +checksum = "be8c97f3a6f02b9e24cadc12aaba75201d18754b53ea0a9d99642f806ccdb4c9" dependencies = [ "clap", ] @@ -273,6 +273,29 @@ dependencies = [ "typenum", ] +[[package]] +name = "cssparser" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e901edd733a1472f944a45116df3f846f54d37e67e68640ac8bb69689aca2aa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "darling" version = "0.20.11" @@ -389,6 +412,21 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + [[package]] name = "elasticlunr-rs" version = "3.0.2" @@ -537,9 +575,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" [[package]] name = "heck" @@ -555,16 +593,14 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "html5ever" -version = "0.27.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +checksum = "953cbbe631aae7fc0a112702ad5d3aaf09da38beaf45ea84610d6e1c358f569c" dependencies = [ "log", "mac", "markup5ever", - "proc-macro2", - "quote", - "syn", + "match_token", ] [[package]] @@ -775,9 +811,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" +checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd" dependencies = [ "jiff-static", "log", @@ -788,9 +824,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" +checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300" dependencies = [ "proc-macro2", "quote", @@ -815,9 +851,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libdbus-sys" @@ -880,16 +916,24 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markup5ever" -version = "0.12.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +checksum = "d0a8096766c229e8c88a3900c9b44b7e06aa7f7343cc229158c3e58ef8f9973a" dependencies = [ "log", - "phf", - "phf_codegen", - "string_cache", - "string_cache_codegen", "tendril", + "web_atoms", +] + +[[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -971,7 +1015,7 @@ dependencies = [ "pulldown-cmark-to-cmark 19.0.1", "serde_json", "thiserror 1.0.69", - "toml 0.8.20", + "toml 0.8.22", ] [[package]] @@ -1154,6 +1198,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ + "phf_macros", "phf_shared", ] @@ -1177,6 +1222,19 @@ dependencies = [ "rand", ] +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "phf_shared" version = "0.11.3" @@ -1224,9 +1282,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -1327,9 +1385,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags 2.9.0", ] @@ -1377,9 +1435,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags 2.9.0", "errno", @@ -1464,9 +1522,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -1530,9 +1588,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -1541,9 +1599,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", @@ -1671,9 +1729,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.20" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" dependencies = [ "serde", "serde_spanned", @@ -1683,26 +1741,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "topological-sort" version = "0.2.2" @@ -1857,6 +1922,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web_atoms" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bcbdcad8fb2e316072ba6bbe09419afdb550285668ac2534f4230a6f2da0ee" +dependencies = [ + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2022,9 +2099,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.6" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" dependencies = [ "memchr", ] From d6183aa9d70e59eaa52ee7938d331a84f24942e9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 4 May 2025 06:09:34 +0200 Subject: [PATCH 126/262] Disable fixpoint for variance computation temporarily --- .../rust-analyzer/crates/hir-ty/src/db.rs | 5 +++-- .../crates/hir-ty/src/variance.rs | 19 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index c24ef16b4969..980ee264b027 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -283,8 +283,9 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::invoke(crate::variance::variances_of)] #[salsa::cycle( - cycle_fn = crate::variance::variances_of_cycle_fn, - cycle_initial = crate::variance::variances_of_cycle_initial, + // cycle_fn = crate::variance::variances_of_cycle_fn, + // cycle_initial = crate::variance::variances_of_cycle_initial, + cycle_result = crate::variance::variances_of_cycle_initial, )] fn variances_of(&self, def: GenericDefId) -> Option>; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index 4e9aa5610a52..6e1cd9a310f1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -22,7 +22,6 @@ use crate::{ use chalk_ir::Mutability; use hir_def::signatures::StructFlags; use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId}; -use salsa::CycleRecoveryAction; use std::fmt; use std::ops::Not; use stdx::never; @@ -55,14 +54,14 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Option>, - _count: u32, - _def: GenericDefId, -) -> CycleRecoveryAction>> { - CycleRecoveryAction::Iterate -} +// pub(crate) fn variances_of_cycle_fn( +// _db: &dyn HirDatabase, +// _result: &Option>, +// _count: u32, +// _def: GenericDefId, +// ) -> salsa::CycleRecoveryAction>> { +// salsa::CycleRecoveryAction::Iterate +// } pub(crate) fn variances_of_cycle_initial( db: &dyn HirDatabase, @@ -966,7 +965,7 @@ struct S3(S); struct FixedPoint(&'static FixedPoint<(), T, U>, V); "#, expect![[r#" - FixedPoint[T: covariant, U: covariant, V: covariant] + FixedPoint[T: bivariant, U: bivariant, V: bivariant] "#]], ); } From eb3a8e5b81db989764a2e8a7568318c6bc8aa986 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 3 May 2025 21:57:19 +0800 Subject: [PATCH 127/262] Make attribute safety validation logic more obvious --- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 61 ++++++++++++++----- .../unsafe-attributes/auxiliary/safe_attr.rs | 7 +++ .../safe-proc-macro-attribute.rs | 22 +++++++ ...e-proc-macro-attribute.unknown_attr.stderr | 14 +++++ 5 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs create mode 100644 tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs create mode 100644 tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 02af26b01567..0994813ecb9c 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -276,7 +276,7 @@ impl<'a> StripUnconfigured<'a> { pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec { validate_attr::check_attribute_safety( &self.sess.psess, - AttributeSafety::Normal, + Some(AttributeSafety::Normal), &cfg_attr, ast::CRATE_NODE_ID, ); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index aa29b24fe910..378cbb846379 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -22,15 +22,13 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) { return; } - let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); - let attr_item = attr.get_normal_item(); + let builtin_attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); - // All non-builtin attributes are considered safe - let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal); - check_attribute_safety(psess, safety, attr, id); + let builtin_attr_safety = builtin_attr_info.map(|x| x.safety); + check_attribute_safety(psess, builtin_attr_safety, attr, id); // Check input tokens for built-in and key-value attributes. - match attr_info { + match builtin_attr_info { // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => { match parse_meta(psess, attr) { @@ -44,6 +42,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) { } } _ => { + let attr_item = attr.get_normal_item(); if let AttrArgs::Eq { .. } = attr_item.args { // All key-value attributes are restricted to meta-item syntax. match parse_meta(psess, attr) { @@ -157,14 +156,21 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte pub fn check_attribute_safety( psess: &ParseSess, - safety: AttributeSafety, + builtin_attr_safety: Option, attr: &Attribute, id: NodeId, ) { let attr_item = attr.get_normal_item(); + match (builtin_attr_safety, attr_item.unsafety) { + // - Unsafe builtin attribute + // - User wrote `#[unsafe(..)]`, which is permitted on any edition + (Some(AttributeSafety::Unsafe { .. }), Safety::Unsafe(..)) => { + // OK + } - if let AttributeSafety::Unsafe { unsafe_since } = safety { - if let ast::Safety::Default = attr_item.unsafety { + // - Unsafe builtin attribute + // - User did not write `#[unsafe(..)]` + (Some(AttributeSafety::Unsafe { unsafe_since }), Safety::Default) => { let path_span = attr_item.path.span; // If the `attr_item`'s span is not from a macro, then just suggest @@ -199,11 +205,38 @@ pub fn check_attribute_safety( ); } } - } else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety { - psess.dcx().emit_err(errors::InvalidAttrUnsafe { - span: unsafe_span, - name: attr_item.path.clone(), - }); + + // - Normal builtin attribute, or any non-builtin attribute + // - All non-builtin attributes are currently considered safe; writing `#[unsafe(..)]` is + // not permitted on non-builtin attributes or normal builtin attributes + (Some(AttributeSafety::Normal) | None, Safety::Unsafe(unsafe_span)) => { + psess.dcx().emit_err(errors::InvalidAttrUnsafe { + span: unsafe_span, + name: attr_item.path.clone(), + }); + } + + // - Normal builtin attribute + // - No explicit `#[unsafe(..)]` written. + (Some(AttributeSafety::Normal), Safety::Default) => { + // OK + } + + // - Non-builtin attribute + // - No explicit `#[unsafe(..)]` written. + (None, Safety::Default) => { + // OK + } + + ( + Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None, + Safety::Safe(..), + ) => { + psess.dcx().span_delayed_bug( + attr_item.span(), + "`check_attribute_safety` does not expect `Safety::Safe` on attributes", + ); + } } } diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs new file mode 100644 index 000000000000..161b71b9737b --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs @@ -0,0 +1,7 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn safe(_attr: TokenStream, item: TokenStream) -> TokenStream { + item +} diff --git a/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs new file mode 100644 index 000000000000..56b7001bdbf0 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs @@ -0,0 +1,22 @@ +//! Anti-regression test for `#[safe]` proc-macro attribute. + +//@ revisions: unknown_attr proc_macro_attr +//@[proc_macro_attr] proc-macro: safe_attr.rs +//@[proc_macro_attr] check-pass + +#![warn(unsafe_attr_outside_unsafe)] + +#[cfg(proc_macro_attr)] +extern crate safe_attr; +#[cfg(proc_macro_attr)] +use safe_attr::safe; + +#[safe] +//[unknown_attr]~^ ERROR cannot find attribute `safe` in this scope +fn foo() {} + +#[safe(no_mangle)] +//[unknown_attr]~^ ERROR cannot find attribute `safe` in this scope +fn bar() {} + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr new file mode 100644 index 000000000000..93c6d75e52ff --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr @@ -0,0 +1,14 @@ +error: cannot find attribute `safe` in this scope + --> $DIR/safe-proc-macro-attribute.rs:18:3 + | +LL | #[safe(no_mangle)] + | ^^^^ + +error: cannot find attribute `safe` in this scope + --> $DIR/safe-proc-macro-attribute.rs:14:3 + | +LL | #[safe] + | ^^^^ + +error: aborting due to 2 previous errors + From de44231d22eea1d1d27fab8d020557323996bb52 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 4 May 2025 16:41:42 +0300 Subject: [PATCH 128/262] implement `PanicTracker` to track `t` panics Trying to understand panics triggered by `t` macro calls is very exhausting (especially on CI failures) because it doesn't provide any information about where the macro was originally invoked. This change adds that missing information when an inner call inside the `t` macro panics. Signed-off-by: onur-ozkan --- src/bootstrap/src/lib.rs | 1 + src/bootstrap/src/utils/helpers.rs | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 88d181532a7f..1e6acad5c0fc 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -53,6 +53,7 @@ use tracing::{instrument, span}; pub use utils::change_tracker::{ CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes, }; +pub use utils::helpers::PanicTracker; use crate::core::build_steps::vendor::VENDOR_DIR; diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 1299fbb7d629..b31b2757767c 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -7,8 +7,9 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::sync::OnceLock; +use std::thread::panicking; use std::time::{Instant, SystemTime, UNIX_EPOCH}; -use std::{env, fs, io, str}; +use std::{env, fs, io, panic, str}; use build_helper::util::fail; use object::read::archive::ArchiveFile; @@ -22,6 +23,23 @@ pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var}; #[cfg(test)] mod tests; +/// A wrapper around `std::panic::Location` used to track the location of panics +/// triggered by `t` macro usage. +pub struct PanicTracker<'a>(pub &'a panic::Location<'a>); + +impl Drop for PanicTracker<'_> { + fn drop(&mut self) { + if panicking() { + eprintln!( + "Panic was initiated from {}:{}:{}", + self.0.file(), + self.0.line(), + self.0.column() + ); + } + } +} + /// A helper macro to `unwrap` a result except also print out details like: /// /// * The file/line of the panic @@ -32,19 +50,21 @@ mod tests; /// using a `Result` with `try!`, but this may change one day... #[macro_export] macro_rules! t { - ($e:expr) => { + ($e:expr) => {{ + let _panic_guard = $crate::PanicTracker(std::panic::Location::caller()); match $e { Ok(e) => e, Err(e) => panic!("{} failed with {}", stringify!($e), e), } - }; + }}; // it can show extra info in the second parameter - ($e:expr, $extra:expr) => { + ($e:expr, $extra:expr) => {{ + let _panic_guard = $crate::PanicTracker(std::panic::Location::caller()); match $e { Ok(e) => e, Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra), } - }; + }}; } pub use t; From 56d6b4e427c271e8f069500f6fac4e209e946144 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 May 2025 17:56:07 +0300 Subject: [PATCH 129/262] compiletest: Support matching on non-json lines in compiler output and migrate most of remaining `error-pattern`s to it. --- src/doc/rustc-dev-guide/src/tests/ui.md | 6 ++- src/tools/compiletest/src/errors.rs | 3 ++ src/tools/compiletest/src/json.rs | 32 +++++-------- src/tools/compiletest/src/runtest.rs | 43 ++++++++--------- .../compiletest/src/runtest/incremental.rs | 14 ++---- src/tools/compiletest/src/runtest/ui.rs | 47 ++++--------------- tests/incremental/ich_nested_items.rs | 1 + tests/incremental/incremental_proc_macro.rs | 2 +- tests/incremental/issue-49595/issue-49595.rs | 2 +- tests/incremental/issue-84252-global-alloc.rs | 1 + .../issue-85360-eval-obligation-ice.rs | 2 + tests/incremental/no_mangle.rs | 1 + .../thinlto/cgu_keeps_identical_fn.rs | 4 +- tests/incremental/unrecoverable_query.rs | 2 + tests/rustdoc-ui/ice-bug-report-url.rs | 5 +- tests/rustdoc-ui/ice-bug-report-url.stderr | 2 +- .../issues/issue-81662-shortness.rs | 3 +- .../issues/issue-81662-shortness.stdout | 8 ++-- .../issues/issue-83883-describe-lints.rs | 5 +- tests/ui/annotate-snippet/missing-type.rs | 3 +- tests/ui/annotate-snippet/missing-type.stderr | 2 +- tests/ui/annotate-snippet/multispan.rs | 3 +- tests/ui/annotate-snippet/multispan.stderr | 14 +++--- tests/ui/bootstrap/rustc_bootstrap.rs | 3 +- .../compile-flags-last.rs | 3 +- .../cfg-arg-invalid-7.rs | 5 +- .../debuginfo-type-name-layout-ice-94961-2.rs | 6 +-- tests/ui/diagnostic-width/flag-json.rs | 5 +- tests/ui/diagnostic-width/flag-json.stderr | 6 +-- tests/ui/error-emitter/highlighting.rs | 3 +- tests/ui/error-emitter/highlighting.svg | 4 +- .../ui/error-emitter/highlighting.windows.svg | 4 +- .../multiline-multipart-suggestion.rs | 3 +- .../multiline-multipart-suggestion.svg | 6 +-- ...multiline-multipart-suggestion.windows.svg | 6 +-- ...-between-expected-trait-and-found-trait.rs | 3 +- ...between-expected-trait-and-found-trait.svg | 6 +-- .../emit-output-types-without-args.rs | 3 +- tests/ui/json/json-bom-plus-crlf-multifile.rs | 5 ++ tests/ui/json/json-bom-plus-crlf.rs | 4 ++ tests/ui/json/json-bom-plus-crlf.stderr | 6 +-- tests/ui/json/json-short.rs | 1 + tests/ui/json/json-short.stderr | 2 +- .../lint/unused_parens_json_suggestion.fixed | 2 +- .../ui/lint/unused_parens_json_suggestion.rs | 2 +- .../lint/unused_parens_json_suggestion.stderr | 6 +-- ...unused_parens_remove_json_suggestion.fixed | 10 +++- .../unused_parens_remove_json_suggestion.rs | 10 +++- ...nused_parens_remove_json_suggestion.stderr | 36 +++++++------- tests/ui/mir/lint/assignment-overlap.rs | 3 +- tests/ui/mir/lint/call-overlap.rs | 3 +- tests/ui/mir/lint/storage-live.rs | 3 +- tests/ui/mir/lint/storage-live.stderr | 4 +- tests/ui/mir/lint/storage-return.rs | 3 +- tests/ui/mir/validate/critical-edge.rs | 4 +- tests/ui/panics/default-backtrace-ice.rs | 7 +-- tests/ui/panics/default-backtrace-ice.stderr | 2 +- tests/ui/treat-err-as-bug/err.rs | 5 +- tests/ui/treat-err-as-bug/err.stderr | 2 +- .../panic-causes-oom-112708.rs | 3 +- tests/ui/treat-err-as-bug/span_delayed_bug.rs | 5 +- .../treat-err-as-bug/span_delayed_bug.stderr | 2 +- tests/ui/unpretty/hir-tree.rs | 3 +- 63 files changed, 208 insertions(+), 196 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index b31c861c947a..721d20b65c5a 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -344,8 +344,7 @@ For checking runtime output, `//@ check-run-results` may be preferable. Only use `error-pattern` if none of the above works. -Line annotations `//~` are still checked in tests using `error-pattern`. -In exceptional cases, use `//@ compile-flags: --error-format=human` to opt out of these checks. +Line annotations `//~` and `error-pattern` are compatible and can be used in the same test. ### Diagnostic kinds (error levels) @@ -356,9 +355,12 @@ The diagnostic kinds that you can have are: - `NOTE` - `HELP` - `SUGGESTION` +- `RAW` The `SUGGESTION` kind is used for specifying what the expected replacement text should be for a diagnostic suggestion. +The `RAW` kind can be used for matching on lines from non-structured output sometimes emitted +by the compiler instead of or in addition to structured json. `ERROR` and `WARN` kinds are required to be exhaustively covered by line annotations `//~` by default. diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index a45f39b036cc..b5a2b7feac9d 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -15,6 +15,7 @@ pub enum ErrorKind { Note, Suggestion, Warning, + Raw, } impl ErrorKind { @@ -39,6 +40,7 @@ impl ErrorKind { "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note, "SUGGESTION" => ErrorKind::Suggestion, "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning, + "RAW" => ErrorKind::Raw, _ => panic!( "unexpected diagnostic kind `{s}`, expected \ `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`" @@ -55,6 +57,7 @@ impl fmt::Display for ErrorKind { ErrorKind::Note => write!(f, "NOTE"), ErrorKind::Suggestion => write!(f, "SUGGESTION"), ErrorKind::Warning => write!(f, "WARN"), + ErrorKind::Raw => write!(f, "RAW"), } } } diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 151ac345125e..6ed2b52c66d2 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -7,7 +7,6 @@ use regex::Regex; use serde::Deserialize; use crate::errors::{Error, ErrorKind}; -use crate::runtest::ProcRes; #[derive(Deserialize)] struct Diagnostic { @@ -140,28 +139,19 @@ pub fn extract_rendered(output: &str) -> String { .collect() } -pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec { +pub fn parse_output(file_name: &str, output: &str) -> Vec { let mut errors = Vec::new(); for line in output.lines() { - // The compiler sometimes intermingles non-JSON stuff into the - // output. This hack just skips over such lines. Yuck. - if line.starts_with('{') { - match serde_json::from_str::(line) { - Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name), - Err(error) => { - // Ignore the future compat report message - this is handled - // by `extract_rendered` - if serde_json::from_str::(line).is_err() { - proc_res.fatal( - Some(&format!( - "failed to decode compiler output as json: `{}`\nline: {}\noutput: {}", - error, line, output - )), - || (), - ); - } - } - } + // Compiler can emit non-json lines in non-`--error-format=json` modes, + // and in some situations even in json mode. + match serde_json::from_str::(line) { + Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name), + Err(_) => errors.push(Error { + line_num: None, + kind: ErrorKind::Raw, + msg: line.to_string(), + require_annotation: false, + }), } } errors diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 97cb82c9e363..40c9f29375b2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -23,7 +23,7 @@ use crate::common::{ output_base_dir, output_base_name, output_testname_unique, }; use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; -use crate::errors::{Error, ErrorKind}; +use crate::errors::{Error, ErrorKind, load_errors}; use crate::header::TestProps; use crate::read2::{Truncated, read2_abbreviated}; use crate::util::{Utf8PathBufExt, add_dylib_path, logv, static_regex}; @@ -577,23 +577,9 @@ impl<'test> TestCx<'test> { } } - fn check_all_error_patterns( - &self, - output_to_check: &str, - proc_res: &ProcRes, - pm: Option, - ) { - if self.props.error_patterns.is_empty() && self.props.regex_error_patterns.is_empty() { - if pm.is_some() { - // FIXME(#65865) - return; - } else { - self.fatal(&format!("no error pattern specified in {}", self.testpaths.file)); - } - } - + /// Check `error-pattern` and `regex-error-pattern` directives. + fn check_all_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) { let mut missing_patterns: Vec = Vec::new(); - self.check_error_patterns(output_to_check, &mut missing_patterns); self.check_regex_error_patterns(output_to_check, proc_res, &mut missing_patterns); @@ -670,7 +656,9 @@ impl<'test> TestCx<'test> { } } - fn check_expected_errors(&self, expected_errors: Vec, proc_res: &ProcRes) { + /// Check `//~ KIND message` annotations. + fn check_expected_errors(&self, proc_res: &ProcRes) { + let expected_errors = load_errors(&self.testpaths.file, self.revision); debug!( "check_expected_errors: expected_errors={:?} proc_res.status={:?}", expected_errors, proc_res.status @@ -711,11 +699,24 @@ impl<'test> TestCx<'test> { .collect(); // Parse the JSON output from the compiler and extract out the messages. - let actual_errors = json::parse_output(&diagnostic_file_name, &proc_res.stderr, proc_res); + let actual_errors = json::parse_output(&diagnostic_file_name, &self.get_output(proc_res)) + .into_iter() + .map(|e| Error { msg: self.normalize_output(&e.msg, &[]), ..e }); + let mut unexpected = Vec::new(); let mut found = vec![false; expected_errors.len()]; - for mut actual_error in actual_errors { - actual_error.msg = self.normalize_output(&actual_error.msg, &[]); + for actual_error in actual_errors { + for pattern in &self.props.error_patterns { + let pattern = pattern.trim(); + if actual_error.msg.contains(pattern) { + let q = if actual_error.line_num.is_none() { "?" } else { "" }; + self.fatal(&format!( + "error pattern '{pattern}' is found in structured \ + diagnostics, use `//~{q} {} {pattern}` instead", + actual_error.kind, + )); + } + } let opt_index = expected_errors.iter().enumerate().position(|(index, expected_error)| { diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs index ea985866a052..90cff6bab4dc 100644 --- a/src/tools/compiletest/src/runtest/incremental.rs +++ b/src/tools/compiletest/src/runtest/incremental.rs @@ -100,16 +100,8 @@ impl TestCx<'_> { self.check_no_compiler_crash(&proc_res, self.props.should_ice); let output_to_check = self.get_output(&proc_res); - let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); - if !expected_errors.is_empty() { - if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty() - { - self.fatal("both error pattern and expected errors specified"); - } - self.check_expected_errors(expected_errors, &proc_res); - } else { - self.check_all_error_patterns(&output_to_check, &proc_res, pm); - } + self.check_expected_errors(&proc_res); + self.check_all_error_patterns(&output_to_check, &proc_res); if self.props.should_ice { match proc_res.status.code() { Some(101) => (), @@ -137,6 +129,6 @@ impl TestCx<'_> { let output_to_check = self.get_output(&proc_res); self.check_correct_failure_status(&proc_res); - self.check_all_error_patterns(&output_to_check, &proc_res, pm); + self.check_all_error_patterns(&output_to_check, &proc_res); } } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index cf0ae14f81bf..cc50a918f757 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -9,7 +9,7 @@ use super::{ AllowUnused, Emit, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, TestOutput, Truncated, UI_FIXED, WillExecute, }; -use crate::{errors, json}; +use crate::json; impl TestCx<'_> { pub(super) fn run_ui_test(&self) { @@ -127,9 +127,7 @@ impl TestCx<'_> { ); } - let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); - - if let WillExecute::Yes = should_run { + let output_to_check = if let WillExecute::Yes = should_run { let proc_res = self.exec_compiled_test(); let run_output_errors = if self.props.check_run_results { self.load_compare_outputs(&proc_res, TestOutput::Run, explicit) @@ -150,44 +148,19 @@ impl TestCx<'_> { self.fatal_proc_rec("test run succeeded!", &proc_res); } - let output_to_check = self.get_output(&proc_res); - if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty() - { - // "// error-pattern" comments - self.check_all_error_patterns(&output_to_check, &proc_res, pm); - } - self.check_forbid_output(&output_to_check, &proc_res) - } + self.get_output(&proc_res) + } else { + self.get_output(&proc_res) + }; debug!( - "run_ui_test: explicit={:?} config.compare_mode={:?} expected_errors={:?} \ + "run_ui_test: explicit={:?} config.compare_mode={:?} \ proc_res.status={:?} props.error_patterns={:?}", - explicit, - self.config.compare_mode, - expected_errors, - proc_res.status, - self.props.error_patterns + explicit, self.config.compare_mode, proc_res.status, self.props.error_patterns ); - if !explicit && self.config.compare_mode.is_none() { - // "//~ERROR comments" - self.check_expected_errors(expected_errors, &proc_res); - } else if explicit && !expected_errors.is_empty() { - let msg = format!( - "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead", - expected_errors[0].line_num_str(), - expected_errors[0].kind, - ); - self.fatal(&msg); - } - let output_to_check = self.get_output(&proc_res); - if should_run == WillExecute::No - && (!self.props.error_patterns.is_empty() - || !self.props.regex_error_patterns.is_empty()) - { - // "// error-pattern" comments - self.check_all_error_patterns(&output_to_check, &proc_res, pm); - } + self.check_expected_errors(&proc_res); + self.check_all_error_patterns(&output_to_check, &proc_res); self.check_forbid_output(&output_to_check, &proc_res); if self.props.run_rustfix && self.config.compare_mode.is_none() { diff --git a/tests/incremental/ich_nested_items.rs b/tests/incremental/ich_nested_items.rs index 19628e0bce1b..c2a041ba268c 100644 --- a/tests/incremental/ich_nested_items.rs +++ b/tests/incremental/ich_nested_items.rs @@ -7,6 +7,7 @@ #![crate_type = "rlib"] #![feature(rustc_attrs)] +#![allow(dead_code)] #[rustc_clean(except = "opt_hir_owner_nodes", cfg = "cfail2")] pub fn foo() { diff --git a/tests/incremental/incremental_proc_macro.rs b/tests/incremental/incremental_proc_macro.rs index 3cf89cae6528..fc32aad5645c 100644 --- a/tests/incremental/incremental_proc_macro.rs +++ b/tests/incremental/incremental_proc_macro.rs @@ -12,5 +12,5 @@ extern crate incremental_proc_macro_aux; #[derive(IncrementalMacro)] pub struct Foo { - x: u32 + _x: u32 } diff --git a/tests/incremental/issue-49595/issue-49595.rs b/tests/incremental/issue-49595/issue-49595.rs index a291188f746e..7fe843135dfe 100644 --- a/tests/incremental/issue-49595/issue-49595.rs +++ b/tests/incremental/issue-49595/issue-49595.rs @@ -10,7 +10,7 @@ mod tests { #[cfg_attr(not(cfail1), test)] - fn test() { + fn _test() { } } diff --git a/tests/incremental/issue-84252-global-alloc.rs b/tests/incremental/issue-84252-global-alloc.rs index 8dc611df9d87..cd2cb2313bd3 100644 --- a/tests/incremental/issue-84252-global-alloc.rs +++ b/tests/incremental/issue-84252-global-alloc.rs @@ -1,5 +1,6 @@ //@ revisions: cfail1 cfail2 //@ build-pass +//@ needs-crate-type: cdylib #![crate_type="lib"] #![crate_type="cdylib"] diff --git a/tests/incremental/issue-85360-eval-obligation-ice.rs b/tests/incremental/issue-85360-eval-obligation-ice.rs index 70bb43f39ecf..2148e45bb387 100644 --- a/tests/incremental/issue-85360-eval-obligation-ice.rs +++ b/tests/incremental/issue-85360-eval-obligation-ice.rs @@ -4,6 +4,8 @@ //@ edition: 2021 //@ build-pass +#![allow(dead_code)] + use core::any::Any; use core::marker::PhantomData; diff --git a/tests/incremental/no_mangle.rs b/tests/incremental/no_mangle.rs index 1a01a40113a2..36b82a7b863c 100644 --- a/tests/incremental/no_mangle.rs +++ b/tests/incremental/no_mangle.rs @@ -1,6 +1,7 @@ //@ revisions:cfail1 cfail2 //@ check-pass //@ compile-flags: --crate-type cdylib +//@ needs-crate-type: cdylib #![deny(unused_attributes)] diff --git a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs index 5751759223b9..d124a3498c4a 100644 --- a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs +++ b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs @@ -33,12 +33,12 @@ mod foo { // Trivial functions like this one are imported very reliably by ThinLTO. - #[cfg(any(cfail1, cfail4))] + #[cfg(cfail1)] pub fn inlined_fn() -> u32 { 1234 } - #[cfg(not(any(cfail1, cfail4)))] + #[cfg(not(cfail1))] pub fn inlined_fn() -> u32 { 1234 } diff --git a/tests/incremental/unrecoverable_query.rs b/tests/incremental/unrecoverable_query.rs index e17236bebd25..798a418f7990 100644 --- a/tests/incremental/unrecoverable_query.rs +++ b/tests/incremental/unrecoverable_query.rs @@ -8,6 +8,8 @@ //@ compile-flags: --crate-type=lib //@ build-pass +#![allow(dead_code)] + pub trait P { type A; } diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index 9260644e44f1..2e384fa1be62 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Ztreat-err-as-bug //@ rustc-env:RUSTC_ICE=0 //@ failure-status: 101 -//@ error-pattern: aborting due to -//@ error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md //@ normalize-stderr: "note: compiler flags.*\n\n" -> "" //@ normalize-stderr: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" @@ -13,3 +11,6 @@ fn wrong() //~^ ERROR expected one of + +//~? RAW aborting due to +//~? RAW we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr index 14a961c2ce01..b6eb8a1792df 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.stderr +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -1,5 +1,5 @@ error: internal compiler error: expected one of `->`, `where`, or `{`, found `` - --> $DIR/ice-bug-report-url.rs:14:10 + --> $DIR/ice-bug-report-url.rs:12:10 | LL | fn wrong() | ^ expected one of `->`, `where`, or `{` diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs index 8719442c34f9..5d1951dbe3ee 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -1,6 +1,5 @@ //@ compile-flags:--test --error-format=short //@ check-stdout -//@ error-pattern:cannot find function `foo` //@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 @@ -11,3 +10,5 @@ fn foo() { println!("Hello, world!"); } + +//~? RAW cannot find function `foo` diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout index 8fcc7ed272f0..94a82cf0afc4 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout @@ -1,16 +1,16 @@ running 1 test -test $DIR/issue-81662-shortness.rs - foo (line 8) ... FAILED +test $DIR/issue-81662-shortness.rs - foo (line 7) ... FAILED failures: ----- $DIR/issue-81662-shortness.rs - foo (line 8) stdout ---- -$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` in this scope: not found in this scope +---- $DIR/issue-81662-shortness.rs - foo (line 7) stdout ---- +$DIR/issue-81662-shortness.rs:8:1: error[E0425]: cannot find function `foo` in this scope: not found in this scope error: aborting due to 1 previous error Couldn't compile the test. failures: - $DIR/issue-81662-shortness.rs - foo (line 8) + $DIR/issue-81662-shortness.rs - foo (line 7) test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs index 35d2fda45850..62a0942df1b1 100644 --- a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs @@ -1,10 +1,11 @@ //@ compile-flags: -W help //@ check-pass //@ check-stdout -//@ error-pattern:Lint checks provided -//@ error-pattern:rustdoc::broken-intra-doc-links // // ignore-tidy-linelength // //@ normalize-stdout: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" //@ normalize-stdout: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" + +//~? RAW Lint checks provided +//~? RAW rustdoc::broken-intra-doc-links diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs index ea1c2521103e..bfe8ab2f5ffe 100644 --- a/tests/ui/annotate-snippet/missing-type.rs +++ b/tests/ui/annotate-snippet/missing-type.rs @@ -1,6 +1,7 @@ //@ compile-flags: --error-format human-annotate-rs -Z unstable-options -//@ error-pattern:cannot find type `Iter` in this scope pub fn main() { let x: Iter; } + +//~? RAW cannot find type `Iter` in this scope diff --git a/tests/ui/annotate-snippet/missing-type.stderr b/tests/ui/annotate-snippet/missing-type.stderr index 89ce19c182f5..c16f022a77fa 100644 --- a/tests/ui/annotate-snippet/missing-type.stderr +++ b/tests/ui/annotate-snippet/missing-type.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Iter` in this scope - --> $DIR/missing-type.rs:5:12 + --> $DIR/missing-type.rs:4:12 | LL | let x: Iter; | ^^^^ not found in this scope diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs index b7cf22eebcbf..c2054f62d24c 100644 --- a/tests/ui/annotate-snippet/multispan.rs +++ b/tests/ui/annotate-snippet/multispan.rs @@ -1,5 +1,4 @@ //@ proc-macro: multispan.rs -//@ error-pattern:hello to you, too! //@ compile-flags: --error-format human-annotate-rs -Z unstable-options #![feature(proc_macro_hygiene)] @@ -27,3 +26,5 @@ fn main() { hello!(whoah. hi di hi di ho); hello!(hi good hi and good bye); } + +//~? RAW hello to you, too! diff --git a/tests/ui/annotate-snippet/multispan.stderr b/tests/ui/annotate-snippet/multispan.stderr index 833b67730325..baed54c59a4e 100644 --- a/tests/ui/annotate-snippet/multispan.stderr +++ b/tests/ui/annotate-snippet/multispan.stderr @@ -1,41 +1,41 @@ error: hello to you, too! - --> $DIR/multispan.rs:16:5 + --> $DIR/multispan.rs:15:5 | LL | hello!(hi); | ^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:19:5 + --> $DIR/multispan.rs:18:5 | LL | hello!(hi hi); | ^^^^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:22:5 + --> $DIR/multispan.rs:21:5 | LL | hello!(hi hi hi); | ^^^^^^^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:25:5 + --> $DIR/multispan.rs:24:5 | LL | hello!(hi hey hi yo hi beep beep hi hi); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:26:5 + --> $DIR/multispan.rs:25:5 | LL | hello!(hi there, hi how are you? hi... hi.); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:27:5 + --> $DIR/multispan.rs:26:5 | LL | hello!(whoah. hi di hi di ho); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | error: hello to you, too! - --> $DIR/multispan.rs:28:5 + --> $DIR/multispan.rs:27:5 | LL | hello!(hi good hi and good bye); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/bootstrap/rustc_bootstrap.rs b/tests/ui/bootstrap/rustc_bootstrap.rs index daa28e0cdf29..fb72bba95a15 100644 --- a/tests/ui/bootstrap/rustc_bootstrap.rs +++ b/tests/ui/bootstrap/rustc_bootstrap.rs @@ -38,10 +38,11 @@ // also affected by `RUSTC_BOOTSTRAP`. //@[force_stable] rustc-env:RUSTC_BOOTSTRAP=-1 //@[force_stable] compile-flags: -Z unstable-options -//@[force_stable] regex-error-pattern: error: the option `Z` is only accepted on the nightly compiler #![crate_type = "lib"] // Note: `rustc_attrs` is a perma-unstable internal feature that is unlikely to change, which is // used as a proxy to check `RUSTC_BOOTSTRAP` versus stability checking logic. #![feature(rustc_attrs)] + +//[force_stable]~? RAW the option `Z` is only accepted on the nightly compiler diff --git a/tests/ui/compiletest-self-test/compile-flags-last.rs b/tests/ui/compiletest-self-test/compile-flags-last.rs index b78a64394b87..e0743d2aea58 100644 --- a/tests/ui/compiletest-self-test/compile-flags-last.rs +++ b/tests/ui/compiletest-self-test/compile-flags-last.rs @@ -4,4 +4,5 @@ // next flag as the argument of this flag. // //@ compile-flags: --cap-lints -//@ error-pattern: Argument to option 'cap-lints' missing + +//~? RAW Argument to option 'cap-lints' missing diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs index b4344f1bca5c..f05adc7bf7aa 100644 --- a/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs +++ b/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs @@ -1,5 +1,6 @@ // Regression test for issue #89358. //@ compile-flags: --cfg a" -//@ error-pattern: unterminated double quote string -//@ error-pattern: this error occurred on the command line + +//~? RAW unterminated double quote string +//~? RAW this error occurred on the command line diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs index 08f8ae391fdb..35210e78dcd9 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -1,6 +1,3 @@ -// ignore-tidy-linelength -// FIXME(#140620)~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture - // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that // causes a layout error. // This version of the test already ICE'd before the commit that introduce the ICE described in @@ -8,7 +5,6 @@ //@ compile-flags:-C debuginfo=2 --error-format=human //@ build-fail -//@ error-pattern: values of the type `[u8; usize::MAX]` are too big for the target architecture #![crate_type = "rlib"] @@ -21,4 +17,4 @@ pub fn foo() -> usize { } // FIXME(#140620): the error is reported on different lines on different targets -//FIXME(#140620)~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture +//~? RAW values of the type `[u8; usize::MAX]` are too big for the target architecture diff --git a/tests/ui/diagnostic-width/flag-json.rs b/tests/ui/diagnostic-width/flag-json.rs index 00778872727b..edc7d2e2a425 100644 --- a/tests/ui/diagnostic-width/flag-json.rs +++ b/tests/ui/diagnostic-width/flag-json.rs @@ -1,9 +1,10 @@ //@ compile-flags: --diagnostic-width=20 --error-format=json -//@ error-pattern:expected `()`, found integer // This test checks that `-Z output-width` effects the JSON error output by restricting it to an // arbitrarily low value so that the effect is visible. fn main() { - let _: () = 42; + let _: () = 42; //~ ERROR mismatched types + //~| NOTE expected `()`, found integer + //~| NOTE expected due to this } diff --git a/tests/ui/diagnostic-width/flag-json.stderr b/tests/ui/diagnostic-width/flag-json.stderr index 6a54f86dcee5..cfc0364be76d 100644 --- a/tests/ui/diagnostic-width/flag-json.stderr +++ b/tests/ui/diagnostic-width/flag-json.stderr @@ -24,10 +24,10 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":291,"byte_end":293,"line_start":8,"line_end":8,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":" let _: () = 42;","highlight_start":17,"highlight_end":19}],"label":"expected `()`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/flag-json.rs","byte_start":286,"byte_end":288,"line_start":8,"line_end":8,"column_start":12,"column_end":14,"is_primary":false,"text":[{"text":" let _: () = 42;","highlight_start":12,"highlight_end":14}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0308]: mismatched types - --> $DIR/flag-json.rs:8:17 +"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":244,"byte_end":246,"line_start":7,"line_end":7,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":" let _: () = 42; + --> $DIR/flag-json.rs:7:17 | -LL | ..._: () = 42; +LL | ..._: () = 42; /... | -- ^^ expected `()`, found integer | | | expected due to this diff --git a/tests/ui/error-emitter/highlighting.rs b/tests/ui/error-emitter/highlighting.rs index b3c1acbd342c..d7a0c9d22466 100644 --- a/tests/ui/error-emitter/highlighting.rs +++ b/tests/ui/error-emitter/highlighting.rs @@ -1,7 +1,6 @@ // Make sure "highlighted" code is colored purple //@ compile-flags: --error-format=human --color=always -//@ error-pattern:for<'a>  //@ edition:2018 use core::pin::Pin; @@ -21,3 +20,5 @@ fn wrapped_fn<'a>(_: Box<(dyn Any + Send)>) -> Pin  diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg index 68fc118f1a6e..19818ab6146c 100644 --- a/tests/ui/error-emitter/highlighting.svg +++ b/tests/ui/error-emitter/highlighting.svg @@ -23,7 +23,7 @@ error[E0308]: mismatched types - --> $DIR/highlighting.rs:22:11 + --> $DIR/highlighting.rs:21:11 | @@ -43,7 +43,7 @@ note: function defined here - --> $DIR/highlighting.rs:11:4 + --> $DIR/highlighting.rs:10:4 | diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg index c7dd001434ee..f891bc1d2a68 100644 --- a/tests/ui/error-emitter/highlighting.windows.svg +++ b/tests/ui/error-emitter/highlighting.windows.svg @@ -24,7 +24,7 @@ error[E0308]: mismatched types - --> $DIR/highlighting.rs:22:11 + --> $DIR/highlighting.rs:21:11 | @@ -44,7 +44,7 @@ note: function defined here - --> $DIR/highlighting.rs:11:4 + --> $DIR/highlighting.rs:10:4 | diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.rs b/tests/ui/error-emitter/multiline-multipart-suggestion.rs index a938b280ca2e..92dede1b5d83 100644 --- a/tests/ui/error-emitter/multiline-multipart-suggestion.rs +++ b/tests/ui/error-emitter/multiline-multipart-suggestion.rs @@ -1,5 +1,4 @@ //@ compile-flags: --error-format=human --color=always -//@ error-pattern: missing lifetime specifier fn short(foo_bar: &Vec<&i32>) -> &i32 { &12 @@ -17,3 +16,5 @@ fn long2( &12 } fn main() {} + +//~? RAW missing lifetime specifier diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.svg index c0fb98555ad8..dd84234236d7 100644 --- a/tests/ui/error-emitter/multiline-multipart-suggestion.svg +++ b/tests/ui/error-emitter/multiline-multipart-suggestion.svg @@ -23,7 +23,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:4:34 + --> $DIR/multiline-multipart-suggestion.rs:3:34 | @@ -47,7 +47,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:11:6 + --> $DIR/multiline-multipart-suggestion.rs:10:6 | @@ -83,7 +83,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:16:29 + --> $DIR/multiline-multipart-suggestion.rs:15:29 | diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg index 61b544001f08..144e57165da7 100644 --- a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg +++ b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg @@ -23,7 +23,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:4:34 + --> $DIR/multiline-multipart-suggestion.rs:3:34 | @@ -47,7 +47,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:11:6 + --> $DIR/multiline-multipart-suggestion.rs:10:6 | @@ -83,7 +83,7 @@ error[E0106]: missing lifetime specifier - --> $DIR/multiline-multipart-suggestion.rs:16:29 + --> $DIR/multiline-multipart-suggestion.rs:15:29 | diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs index f1c196a154d5..ffb7a1008e0f 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs @@ -1,6 +1,5 @@ //@ only-linux //@ compile-flags: --error-format=human --color=always -//@ error-pattern: the trait bound trait Foo: Bar {} @@ -18,3 +17,5 @@ fn foo() -> impl Foo { } fn main() {} + +//~? RAW the trait bound diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg index 1a79a9d7efa2..9832e28e008b 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg @@ -1,4 +1,4 @@ - + ) -> i32 { 0 } + //~^ ERROR function with `#[export_stable]` attribute uses type `Box`, which is not exportable +} + +pub mod impl_item { + pub struct S; + + impl S { + #[export_stable] + pub extern "C" fn foo1(&self) -> i32 { 0 } + //~^ ERROR method with `#[export_stable]` attribute uses type `&impl_item::S`, which is not exportable + + #[export_stable] + pub extern "C" fn foo2(self) -> i32 { 0 } + //~^ ERROR method with `#[export_stable]` attribute uses type `impl_item::S`, which is not exportable + } + + pub struct S2(T); + + impl S2 { + #[export_stable] + pub extern "C" fn foo1(&self) {} + //~^ ERROR generic functions are not exportable + } +} + +pub mod tys { + pub trait Trait { + type Type; + } + pub struct S; + + impl Trait for S { + type Type = (u32,); + } + + #[export_stable] + pub extern "C" fn foo1(x: ::Type) -> u32 { x.0 } + //~^ ERROR function with `#[export_stable]` attribute uses type `(u32,)`, which is not exportable + + #[export_stable] + pub type Type = [i32; 4]; + + #[export_stable] + pub extern "C" fn foo2(_x: Type) {} + //~^ ERROR function with `#[export_stable]` attribute uses type `[i32; 4]`, which is not exportable + + impl S { + #[export_stable] + pub type Type = extern "C" fn(); + } + + #[export_stable] + pub extern "C" fn foo3(_x: S::Type) {} + //~^ ERROR function with `#[export_stable]` attribute uses type `extern "C" fn()`, which is not exportable + + #[export_stable] + pub extern "C" fn foo4() -> impl Copy { + //~^ ERROR function with `#[export_stable]` attribute uses type `impl Copy`, which is not exportable + 0 + } +} + +pub mod privacy { + #[export_stable] + #[repr(C)] + pub struct S1 { + pub x: i32 + } + + #[export_stable] + #[repr(C)] + pub struct S2 { + //~^ ERROR ADT types with private fields are not exportable + x: i32 + } + + #[export_stable] + #[repr(i32)] + enum E { + //~^ ERROR private items are not exportable + Variant1 { x: i32 } + } +} + +pub mod use_site { + #[export_stable] + pub trait Trait {} + //~^ ERROR trait's are not exportable + + #[export_stable] + pub const C: i32 = 0; + //~^ ERROR constant's are not exportable +} + +fn main() {} diff --git a/tests/ui/attributes/export/exportable.stderr b/tests/ui/attributes/export/exportable.stderr new file mode 100644 index 000000000000..0f6469d35c3b --- /dev/null +++ b/tests/ui/attributes/export/exportable.stderr @@ -0,0 +1,130 @@ +error: private items are not exportable + --> $DIR/exportable.rs:10:5 + | +LL | pub struct S; + | ^^^^^^^^^^^^ + | +note: is only usable at visibility `pub(crate)` + --> $DIR/exportable.rs:10:5 + | +LL | pub struct S; + | ^^^^^^^^^^^^ + +error: private items are not exportable + --> $DIR/exportable.rs:123:5 + | +LL | enum E { + | ^^^^^^ + | +note: is only usable at visibility `pub(self)` + --> $DIR/exportable.rs:123:5 + | +LL | enum E { + | ^^^^^^ + +error: trait's are not exportable + --> $DIR/exportable.rs:131:5 + | +LL | pub trait Trait {} + | ^^^^^^^^^^^^^^^ + +error: constant's are not exportable + --> $DIR/exportable.rs:135:5 + | +LL | pub const C: i32 = 0; + | ^^^^^^^^^^^^^^^^ + +error: only functions with "C" ABI are exportable + --> $DIR/exportable.rs:13:5 + | +LL | pub fn foo() -> i32 { 0 } + | ^^^^^^^^^^^^^^^^^^^ + +error: types with unstable layout are not exportable + --> $DIR/exportable.rs:27:5 + | +LL | pub struct S3; + | ^^^^^^^^^^^^^ + +error: only functions with "C" ABI are exportable + --> $DIR/exportable.rs:33:5 + | +LL | pub fn foo1() {} + | ^^^^^^^^^^^^^ + +error: function with `#[export_stable]` attribute uses type `Box`, which is not exportable + --> $DIR/exportable.rs:44:5 + | +LL | pub extern "C" fn foo3(x: Box) -> i32 { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^^^ + | | + | not exportable + +error: method with `#[export_stable]` attribute uses type `&impl_item::S`, which is not exportable + --> $DIR/exportable.rs:53:9 + | +LL | pub extern "C" fn foo1(&self) -> i32 { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^-----^^^^^^^^ + | | + | not exportable + +error: method with `#[export_stable]` attribute uses type `impl_item::S`, which is not exportable + --> $DIR/exportable.rs:57:9 + | +LL | pub extern "C" fn foo2(self) -> i32 { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^^ + | | + | not exportable + +error: generic functions are not exportable + --> $DIR/exportable.rs:65:9 + | +LL | pub extern "C" fn foo1(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function with `#[export_stable]` attribute uses type `(u32,)`, which is not exportable + --> $DIR/exportable.rs:81:5 + | +LL | pub extern "C" fn foo1(x: ::Type) -> u32 { x.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^------------------^^^^^^^^ + | | + | not exportable + +error: function with `#[export_stable]` attribute uses type `[i32; 4]`, which is not exportable + --> $DIR/exportable.rs:88:5 + | +LL | pub extern "C" fn foo2(_x: Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^----^ + | | + | not exportable + +error: function with `#[export_stable]` attribute uses type `extern "C" fn()`, which is not exportable + --> $DIR/exportable.rs:97:5 + | +LL | pub extern "C" fn foo3(_x: S::Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^ + | | + | not exportable + +error: function with `#[export_stable]` attribute uses type `impl Copy`, which is not exportable + --> $DIR/exportable.rs:101:5 + | +LL | pub extern "C" fn foo4() -> impl Copy { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------- + | | + | not exportable + +error: ADT types with private fields are not exportable + --> $DIR/exportable.rs:116:5 + | +LL | pub struct S2 { + | ^^^^^^^^^^^^^ + | +note: `x` is private + --> $DIR/exportable.rs:118:9 + | +LL | x: i32 + | ^^^^^^ + +error: aborting due to 16 previous errors + diff --git a/tests/ui/attributes/export/lang-item.rs b/tests/ui/attributes/export/lang-item.rs new file mode 100644 index 000000000000..b923b41a9575 --- /dev/null +++ b/tests/ui/attributes/export/lang-item.rs @@ -0,0 +1,8 @@ +#![feature(no_core, lang_items, export_stable)] +#![allow(incomplete_features)] +#![crate_type = "sdylib"] +#![no_core] + +#[lang = "sized"] +//~^ ERROR lang items are not allowed in stable dylibs +trait Sized {} diff --git a/tests/ui/attributes/export/lang-item.stderr b/tests/ui/attributes/export/lang-item.stderr new file mode 100644 index 000000000000..8c0741bdb6f2 --- /dev/null +++ b/tests/ui/attributes/export/lang-item.stderr @@ -0,0 +1,8 @@ +error: lang items are not allowed in stable dylibs + --> $DIR/lang-item.rs:6:1 + | +LL | #[lang = "sized"] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/feature-gates/feature-gate-export_stable.rs b/tests/ui/feature-gates/feature-gate-export_stable.rs new file mode 100644 index 000000000000..5d05fee059b8 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-export_stable.rs @@ -0,0 +1,5 @@ +#![crate_type="lib"] + +#[export_stable] +//~^ ERROR the `#[export_stable]` attribute is an experimental feature +pub mod a {} diff --git a/tests/ui/feature-gates/feature-gate-export_stable.stderr b/tests/ui/feature-gates/feature-gate-export_stable.stderr new file mode 100644 index 000000000000..6beb52a77e5c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-export_stable.stderr @@ -0,0 +1,13 @@ +error[E0658]: the `#[export_stable]` attribute is an experimental feature + --> $DIR/feature-gate-export_stable.rs:3:1 + | +LL | #[export_stable] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #139939 for more information + = help: add `#![feature(export_stable)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From e6030468dd10ec8ef93b6a50afaceafce0d6d81b Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 4 May 2025 22:29:57 +0200 Subject: [PATCH 134/262] Revert "Avoid unused clones in Cloned and Copied" This reverts commit ed5f31ab01d41a01b7206eafdf97b458dc41141a. --- library/core/src/iter/adapters/cloned.rs | 88 +--------------------- library/core/src/iter/adapters/copied.rs | 95 +++++------------------- 2 files changed, 20 insertions(+), 163 deletions(-) diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 72d746289711..aea6d64281ae 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -1,6 +1,5 @@ use core::num::NonZero; -use crate::cmp::Ordering; use crate::iter::adapters::zip::try_get_unchecked; use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator}; @@ -42,31 +41,13 @@ where self.it.next().cloned() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } - #[inline] - fn count(self) -> usize { - self.it.count() - } - - fn last(self) -> Option { - self.it.last().cloned() - } - - #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { - self.it.advance_by(n) - } - - fn nth(&mut self, n: usize) -> Option { - self.it.nth(n).cloned() - } - fn try_fold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try, { @@ -80,58 +61,6 @@ where self.it.map(T::clone).fold(init, f) } - fn find

(&mut self, mut predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - { - self.it.find(move |x| predicate(&x)).cloned() - } - - fn max_by(self, mut compare: F) -> Option - where - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - self.it.max_by(move |&x, &y| compare(x, y)).cloned() - } - - fn min_by(self, mut compare: F) -> Option - where - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - self.it.min_by(move |&x, &y| compare(x, y)).cloned() - } - - fn cmp(self, other: O) -> Ordering - where - O: IntoIterator, - Self::Item: Ord, - { - self.it.cmp_by(other, |x, y| x.cmp(&y)) - } - - fn partial_cmp(self, other: O) -> Option - where - O: IntoIterator, - Self::Item: PartialOrd, - { - self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y)) - } - - fn eq(self, other: O) -> bool - where - O: IntoIterator, - Self::Item: PartialEq, - { - self.it.eq_by(other, |x, y| x == &y) - } - - fn is_sorted_by(self, mut compare: F) -> bool - where - F: FnMut(&Self::Item, &Self::Item) -> bool, - { - self.it.is_sorted_by(move |&x, &y| compare(x, y)) - } - unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T where Self: TrustedRandomAccessNoCoerce, @@ -152,13 +81,9 @@ where self.it.next_back().cloned() } - #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { - self.it.advance_back_by(n) - } - fn try_rfold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try, { @@ -171,13 +96,6 @@ where { self.it.map(T::clone).rfold(init, f) } - - fn rfind

(&mut self, mut predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - { - self.it.rfind(move |x| predicate(&x)).cloned() - } } #[stable(feature = "iter_cloned", since = "1.1.0")] @@ -186,12 +104,10 @@ where I: ExactSizeIterator, T: Clone, { - #[inline] fn len(&self) -> usize { self.it.len() } - #[inline] fn is_empty(&self) -> bool { self.it.is_empty() } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 73913aa34a9e..23e4e25ab538 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -1,4 +1,3 @@ -use crate::cmp::Ordering; use crate::iter::adapters::zip::try_get_unchecked; use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen}; @@ -49,35 +48,20 @@ where fn next_chunk( &mut self, - ) -> Result<[Self::Item; N], array::IntoIter> { + ) -> Result<[Self::Item; N], array::IntoIter> + where + Self: Sized, + { >::spec_next_chunk(&mut self.it) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.it.size_hint() } - #[inline] - fn count(self) -> usize { - self.it.count() - } - - fn last(self) -> Option { - self.it.last().copied() - } - - #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { - self.it.advance_by(n) - } - - fn nth(&mut self, n: usize) -> Option { - self.it.nth(n).copied() - } - fn try_fold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try, { @@ -91,56 +75,21 @@ where self.it.fold(init, copy_fold(f)) } - fn find

(&mut self, mut predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - { - self.it.find(move |x| predicate(&x)).copied() + fn nth(&mut self, n: usize) -> Option { + self.it.nth(n).copied() } - fn max_by(self, mut compare: F) -> Option - where - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - self.it.max_by(move |&x, &y| compare(x, y)).copied() + fn last(self) -> Option { + self.it.last().copied() } - fn min_by(self, mut compare: F) -> Option - where - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - self.it.min_by(move |&x, &y| compare(x, y)).copied() + fn count(self) -> usize { + self.it.count() } - fn cmp(self, other: O) -> Ordering - where - O: IntoIterator, - Self::Item: Ord, - { - self.it.cmp_by(other, |x, y| x.cmp(&y)) - } - - fn partial_cmp(self, other: O) -> Option - where - O: IntoIterator, - Self::Item: PartialOrd, - { - self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y)) - } - - fn eq(self, other: O) -> bool - where - O: IntoIterator, - Self::Item: PartialEq, - { - self.it.eq_by(other, |x, y| x == &y) - } - - fn is_sorted_by(self, mut compare: F) -> bool - where - F: FnMut(&Self::Item, &Self::Item) -> bool, - { - self.it.is_sorted_by(move |&x, &y| compare(x, y)) + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.it.advance_by(n) } unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T @@ -163,13 +112,9 @@ where self.it.next_back().copied() } - #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { - self.it.advance_back_by(n) - } - fn try_rfold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try, { @@ -183,11 +128,9 @@ where self.it.rfold(init, copy_fold(f)) } - fn rfind

(&mut self, mut predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - { - self.it.rfind(move |x| predicate(&x)).copied() + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.it.advance_back_by(n) } } @@ -197,12 +140,10 @@ where I: ExactSizeIterator, T: Copy, { - #[inline] fn len(&self) -> usize { self.it.len() } - #[inline] fn is_empty(&self) -> bool { self.it.is_empty() } From 52d806a7c0b8523af013e7f3fd67480884a396c8 Mon Sep 17 00:00:00 2001 From: Nick Kocharhook Date: Sun, 19 Jan 2025 15:35:49 +0000 Subject: [PATCH 135/262] extract_if's sample equivalent now really equivalent. Simpler predicate. Compare sample code output to that of the library function. --- library/alloc/src/vec/mod.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 65a83cb98ba6..788cb1ae8947 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3666,21 +3666,27 @@ impl Vec { /// Using this method is equivalent to the following code: /// /// ``` - /// # use std::cmp::min; - /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 }; - /// # let mut vec = vec![1, 2, 3, 4, 5, 6]; - /// # let range = 1..4; + /// # let some_predicate = |x: &mut i32| { *x % 2 == 1 }; + /// # let mut vec = vec![0, 1, 2, 3, 4, 5, 6]; + /// # let mut vec2 = vec.clone(); + /// # let range = 1..5; /// let mut i = range.start; - /// while i < min(vec.len(), range.end) { + /// let end_items = vec.len() - range.end; + /// # let mut extracted = vec![]; + /// + /// while i < vec.len() - end_items { /// if some_predicate(&mut vec[i]) { /// let val = vec.remove(i); + /// # extracted.push(val); /// // your code here /// } else { /// i += 1; /// } /// } /// - /// # assert_eq!(vec, vec![1, 4, 5]); + /// # let extracted2: Vec<_> = vec2.extract_if(range, some_predicate).collect(); + /// # assert_eq!(vec, vec2); + /// # assert_eq!(extracted, extracted2); /// ``` /// /// But `extract_if` is easier to use. `extract_if` is also more efficient, From 435fc7d685115cf5bbd986ade8d2327ee6441759 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 4 May 2025 22:54:55 +0000 Subject: [PATCH 136/262] Update `compiler-builtins` to 0.1.157 Includes the following changes: * Use runtime feature detection for fma routines on x86 [1] Fixes: https://github.com/rust-lang/rust/issues/140452 [1]: https://github.com/rust-lang/compiler-builtins/pull/896 --- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index f5c04a3bf48c..3df15316d985 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.156" +version = "0.1.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ffbd2789fe5bb95b96a2e22cbe3128239dc46ff0374e0d38e9f102062d7055" +checksum = "74f103f5a97b25e3ed7134dee586e90bbb0496b33ba41816f0e7274e5bb73b50" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 994221de8663..ebfcf8759fa1 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -16,7 +16,7 @@ bench = false [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.156", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.157", features = ['rustc-dep-of-std'] } [features] compiler-builtins-mem = ['compiler_builtins/mem'] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index d7bd28b5279d..06bec74523bb 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.156" } +compiler_builtins = { version = "=0.1.157" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From 07d38eec30d21e1e63a76583cdd23cbd89036ad5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 4 May 2025 19:57:12 -0400 Subject: [PATCH 137/262] Temporarily downgrade backtrace to 0.3.71 --- Cargo.lock | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 967da170476e..a95d66b6ca87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli", + "gimli 0.28.1", ] [[package]] @@ -168,7 +168,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4" dependencies = [ - "object", + "object 0.36.7", ] [[package]] @@ -233,17 +233,17 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", + "cc", "cfg-if", "libc", - "miniz_oxide 0.8.8", - "object", + "miniz_oxide 0.7.4", + "object 0.32.2", "rustc-demangle", - "windows-targets 0.52.6", ] [[package]] @@ -1452,6 +1452,12 @@ dependencies = [ "wasi 0.14.2+wasi-0.2.4", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "gimli" version = "0.31.1" @@ -2062,7 +2068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -2476,6 +2482,15 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "object" version = "0.36.7" @@ -3089,9 +3104,9 @@ version = "0.2.0" dependencies = [ "bstr", "build_helper", - "gimli", + "gimli 0.31.1", "libc", - "object", + "object 0.36.7", "regex", "serde_json", "similar", @@ -3398,11 +3413,11 @@ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ "bitflags", - "gimli", + "gimli 0.31.1", "itertools", "libc", "measureme", - "object", + "object 0.36.7", "rustc-demangle", "rustc_abi", "rustc_ast", @@ -3443,7 +3458,7 @@ dependencies = [ "either", "itertools", "libc", - "object", + "object 0.36.7", "pathdiff", "regex", "rustc_abi", @@ -4459,7 +4474,7 @@ name = "rustc_target" version = "0.0.0" dependencies = [ "bitflags", - "object", + "object 0.36.7", "rustc_abi", "rustc_data_structures", "rustc_fs_util", @@ -5225,9 +5240,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e9c1e705f82a260173f3eec93f2ff6d7807f23ad5a8cc2e7316a891733ea7a1" dependencies = [ - "gimli", + "gimli 0.31.1", "hashbrown", - "object", + "object 0.36.7", "tracing", ] From e5879018ef648e990f8af9d638db456a9fac07e3 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 4 May 2025 19:55:09 -0700 Subject: [PATCH 138/262] move logic for telling whether to peel smart pointers into a helper The new logic for determining whether to peel references will depend on whether smart pointers need to be peeled before matching. --- compiler/rustc_hir_typeck/src/pat.rs | 44 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 7520782930a2..ea335c7a4a7b 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -531,24 +531,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If `deref_patterns` is enabled, peel a smart pointer from the scrutinee type. See the // examples in `tests/ui/pattern/deref_patterns/`. _ if self.tcx.features().deref_patterns() - && let AdjustMode::Peel { kind: PeelKind::Implicit { until_adt } } = adjust_mode + && let AdjustMode::Peel { kind: peel_kind } = adjust_mode && pat.default_binding_modes - // For simplicity, only apply overloaded derefs if `expected` is a known ADT. - // FIXME(deref_patterns): we'll get better diagnostics for users trying to - // implicitly deref generics if we allow them here, but primitives, tuples, and - // inference vars definitely should be stopped. Figure out what makes most sense. - && let ty::Adt(scrutinee_adt, _) = *expected.kind() - // Don't peel if the pattern type already matches the scrutinee. E.g., stop here if - // matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern. - && until_adt != Some(scrutinee_adt.did()) - // At this point, the pattern isn't able to match `expected` without peeling. Check - // that it implements `Deref` before assuming it's a smart pointer, to get a normal - // type error instead of a missing impl error if not. This only checks for `Deref`, - // not `DerefPure`: we require that too, but we want a trait error if it's missing. - && let Some(deref_trait) = self.tcx.lang_items().deref_trait() - && self - .type_implements_trait(deref_trait, [expected], self.param_env) - .may_apply() => + && self.should_peel_smart_pointer(peel_kind, expected) => { debug!("scrutinee ty {expected:?} is a smart pointer, inserting overloaded deref"); // The scrutinee is a smart pointer; implicitly dereference it. This adds a @@ -720,6 +705,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Determine whether `expected` is a smart pointer type that should be peeled before matching. + fn should_peel_smart_pointer(&self, peel_kind: PeelKind, expected: Ty<'tcx>) -> bool { + // Explicit `deref!(_)` patterns match against smart pointers; don't peel in that case. + if let PeelKind::Implicit { until_adt, .. } = peel_kind + // For simplicity, only apply overloaded derefs if `expected` is a known ADT. + // FIXME(deref_patterns): we'll get better diagnostics for users trying to + // implicitly deref generics if we allow them here, but primitives, tuples, and + // inference vars definitely should be stopped. Figure out what makes most sense. + && let ty::Adt(scrutinee_adt, _) = *expected.kind() + // Don't peel if the pattern type already matches the scrutinee. E.g., stop here if + // matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern. + && until_adt != Some(scrutinee_adt.did()) + // At this point, the pattern isn't able to match `expected` without peeling. Check + // that it implements `Deref` before assuming it's a smart pointer, to get a normal + // type error instead of a missing impl error if not. This only checks for `Deref`, + // not `DerefPure`: we require that too, but we want a trait error if it's missing. + && let Some(deref_trait) = self.tcx.lang_items().deref_trait() + && self.type_implements_trait(deref_trait, [expected], self.param_env).may_apply() + { + true + } else { + false + } + } + fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> { let ty = match <.kind { rustc_hir::PatExprKind::Lit { lit, negated } => { From e4272d12f29dc425679749a1fb7569bd25464e88 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Wed, 9 Apr 2025 16:40:50 +0530 Subject: [PATCH 139/262] feat: Added capability to add multiple dependencies for an LLVMFeature --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 37 +++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 264510285a59..f8706c5ee2fa 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -19,6 +19,7 @@ use rustc_session::config::{PrintKind, PrintRequest}; use rustc_span::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport}; use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES}; +use smallvec::{SmallVec, smallvec}; use crate::back::write::create_informational_target_machine; use crate::errors::{ @@ -180,27 +181,27 @@ impl<'a> TargetFeatureFoldStrength<'a> { pub(crate) struct LLVMFeature<'a> { llvm_feature_name: &'a str, - dependency: Option>, + dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>, } impl<'a> LLVMFeature<'a> { fn new(llvm_feature_name: &'a str) -> Self { - Self { llvm_feature_name, dependency: None } + Self { llvm_feature_name, dependencies: SmallVec::new() } } - fn with_dependency( + fn with_dependencies( llvm_feature_name: &'a str, - dependency: TargetFeatureFoldStrength<'a>, + dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>, ) -> Self { - Self { llvm_feature_name, dependency: Some(dependency) } + Self { llvm_feature_name, dependencies } } - fn contains(&self, feat: &str) -> bool { + fn contains(&'a self, feat: &str) -> bool { self.iter().any(|dep| dep == feat) } fn iter(&'a self) -> impl Iterator { - let dependencies = self.dependency.iter().map(|feat| feat.as_str()); + let dependencies = self.dependencies.iter().map(|feat| feat.as_str()); std::iter::once(self.llvm_feature_name).chain(dependencies) } } @@ -210,7 +211,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> { type IntoIter = impl Iterator; fn into_iter(self) -> Self::IntoIter { - let dependencies = self.dependency.into_iter().map(|feat| feat.as_str()); + let dependencies = self.dependencies.into_iter().map(|feat| feat.as_str()); std::iter::once(self.llvm_feature_name).chain(dependencies) } } @@ -240,9 +241,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::with_dependency( + ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies( "sse4.2", - TargetFeatureFoldStrength::EnableOnly("crc32"), + smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")], )), ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")), ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")), @@ -262,9 +263,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("b16b16")), ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")), // Rust ties fp and neon together. - ("aarch64", "neon") => { - Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8"))) - } + ("aarch64", "neon") => Some(LLVMFeature::with_dependencies( + "neon", + smallvec![TargetFeatureFoldStrength::Both("fp-armv8")], + )), // In LLVM neon implicitly enables fp, but we manually enable // neon when a feature only implicitly enables fp ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")), @@ -281,9 +283,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option None, // Enable the evex512 target feature if an avx512 target feature is enabled. - ("x86", s) if s.starts_with("avx512") => { - Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))) - } + ("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies( + s, + smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")], + )), // Support for `wide-arithmetic` will first land in LLVM 20 as part of // llvm/llvm-project#111598 ("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None, @@ -853,7 +856,7 @@ pub(crate) fn global_llvm_features( "{}{}", enable_disable, llvm_feature.llvm_feature_name )) - .chain(llvm_feature.dependency.into_iter().filter_map( + .chain(llvm_feature.dependencies.into_iter().filter_map( move |feat| match (enable, feat) { (_, TargetFeatureFoldStrength::Both(f)) | (true, TargetFeatureFoldStrength::EnableOnly(f)) => { From 7845c011dd3bdfb5eaa461476f5f7d0f3aa16dfc Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 5 May 2025 12:16:40 +0200 Subject: [PATCH 140/262] collect all Fuchsia bindings into the `fuchsia` module The Fuchsia bindings are currently spread out across multiple modules in `sys/pal/unix` leading to unnecessary duplication. This PR moves all of these definitions into `sys::pal::unix::fuchsia` and additionally: * deduplicates the definitions * makes the error names consistent * marks some extern functions as safe * removes unused items (there's no need to maintain these bindings if we're not going to use them) * removes the documentation for the definitions (contributors should always consult the platform documentation, duplicating that here is just an extra maintenance burden) --- library/std/src/sys/pal/unix/fuchsia.rs | 323 +++++++------------- library/std/src/sys/pal/unix/futex.rs | 54 +--- library/std/src/sys/pal/unix/thread.rs | 19 +- library/std/src/sys/process/unix/fuchsia.rs | 4 +- library/std/src/sys/sync/mutex/fuchsia.rs | 6 +- 5 files changed, 123 insertions(+), 283 deletions(-) diff --git a/library/std/src/sys/pal/unix/fuchsia.rs b/library/std/src/sys/pal/unix/fuchsia.rs index 7932bd26d76c..c118dee62476 100644 --- a/library/std/src/sys/pal/unix/fuchsia.rs +++ b/library/std/src/sys/pal/unix/fuchsia.rs @@ -1,48 +1,35 @@ -#![allow(non_camel_case_types, unused)] +#![expect(non_camel_case_types)] -use libc::{c_int, c_void, size_t}; +use libc::size_t; +use crate::ffi::{c_char, c_int, c_void}; use crate::io; -use crate::mem::MaybeUninit; -use crate::os::raw::c_char; + +////////// +// Time // +////////// + +pub type zx_time_t = i64; + +pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX; + +unsafe extern "C" { + pub safe fn zx_clock_get_monotonic() -> zx_time_t; +} + +///////////// +// Handles // +///////////// pub type zx_handle_t = u32; -pub type zx_vaddr_t = usize; -pub type zx_rights_t = u32; -pub type zx_status_t = i32; pub const ZX_HANDLE_INVALID: zx_handle_t = 0; -pub type zx_time_t = i64; -pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX; - -pub type zx_signals_t = u32; - -pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3; - -pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3; - -pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31; - -// The upper four bits gives the minor version. -pub type zx_object_info_topic_t = u32; - -pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28); - -pub type zx_info_process_flags_t = u32; - -pub fn zx_cvt(t: T) -> io::Result -where - T: TryInto + Copy, -{ - if let Ok(status) = TryInto::try_into(t) { - if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) } - } else { - Err(io::Error::last_os_error()) - } +unsafe extern "C" { + pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t; } -// Safe wrapper around zx_handle_t +/// A safe wrapper around `zx_handle_t`. pub struct Handle { raw: zx_handle_t, } @@ -65,6 +52,66 @@ impl Drop for Handle { } } +/////////// +// Futex // +/////////// + +pub type zx_futex_t = crate::sync::atomic::Atomic; + +unsafe extern "C" { + pub fn zx_object_wait_one( + handle: zx_handle_t, + signals: zx_signals_t, + timeout: zx_time_t, + pending: *mut zx_signals_t, + ) -> zx_status_t; + + pub fn zx_futex_wait( + value_ptr: *const zx_futex_t, + current_value: zx_futex_t, + new_futex_owner: zx_handle_t, + deadline: zx_time_t, + ) -> zx_status_t; + pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t; + pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t; + pub safe fn zx_thread_self() -> zx_handle_t; +} + +//////////////// +// Properties // +//////////////// + +pub const ZX_PROP_NAME: u32 = 3; + +unsafe extern "C" { + pub fn zx_object_set_property( + handle: zx_handle_t, + property: u32, + value: *const libc::c_void, + value_size: libc::size_t, + ) -> zx_status_t; +} + +///////////// +// Signals // +///////////// + +pub type zx_signals_t = u32; + +pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3; +pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3; + +///////////////// +// Object info // +///////////////// + +// The upper four bits gives the minor version. +pub type zx_object_info_topic_t = u32; + +pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28); + +pub type zx_info_process_flags_t = u32; + // Returned for topic ZX_INFO_PROCESS #[derive(Default)] #[repr(C)] @@ -76,25 +123,6 @@ pub struct zx_info_process_t { } unsafe extern "C" { - pub fn zx_job_default() -> zx_handle_t; - - pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t; - - pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t; - - pub fn zx_handle_duplicate( - handle: zx_handle_t, - rights: zx_rights_t, - out: *const zx_handle_t, - ) -> zx_handle_t; - - pub fn zx_object_wait_one( - handle: zx_handle_t, - signals: zx_signals_t, - timeout: zx_time_t, - pending: *mut zx_signals_t, - ) -> zx_status_t; - pub fn zx_object_get_info( handle: zx_handle_t, topic: u32, @@ -105,6 +133,10 @@ unsafe extern "C" { ) -> zx_status_t; } +/////////////// +// Processes // +/////////////// + #[derive(Default)] #[repr(C)] pub struct fdio_spawn_action_t { @@ -130,6 +162,8 @@ unsafe extern "C" { pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t; pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t; + + pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t; } // fdio_spawn_etc flags @@ -137,173 +171,34 @@ unsafe extern "C" { pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001; pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002; pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004; -pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008; pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010; pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020; -pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF; // fdio_spawn_etc actions -pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001; pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002; -// Errors +//////////// +// Errors // +//////////// -#[allow(unused)] -pub const ERR_INTERNAL: zx_status_t = -1; +pub type zx_status_t = i32; -// ERR_NOT_SUPPORTED: The operation is not implemented, supported, -// or enabled. -#[allow(unused)] -pub const ERR_NOT_SUPPORTED: zx_status_t = -2; +pub const ZX_OK: zx_status_t = 0; +pub const ZX_ERR_NOT_SUPPORTED: zx_status_t = -2; +pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10; +pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11; +pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12; +pub const ZX_ERR_BAD_STATE: zx_status_t = -20; +pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; -// ERR_NO_RESOURCES: The system was not able to allocate some resource -// needed for the operation. -#[allow(unused)] -pub const ERR_NO_RESOURCES: zx_status_t = -3; - -// ERR_NO_MEMORY: The system was not able to allocate memory needed -// for the operation. -#[allow(unused)] -pub const ERR_NO_MEMORY: zx_status_t = -4; - -// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete -// successfully. -#[allow(unused)] -pub const ERR_CALL_FAILED: zx_status_t = -5; - -// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be -// retried. This should not be seen outside of the VDSO. -#[allow(unused)] -pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6; - -// ======= Parameter errors ======= -// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer -#[allow(unused)] -pub const ERR_INVALID_ARGS: zx_status_t = -10; - -// ERR_BAD_HANDLE: A specified handle value does not refer to a handle. -#[allow(unused)] -pub const ERR_BAD_HANDLE: zx_status_t = -11; - -// ERR_WRONG_TYPE: The subject of the operation is the wrong type to -// perform the operation. -// Example: Attempting a message_read on a thread handle. -#[allow(unused)] -pub const ERR_WRONG_TYPE: zx_status_t = -12; - -// ERR_BAD_SYSCALL: The specified syscall number is invalid. -#[allow(unused)] -pub const ERR_BAD_SYSCALL: zx_status_t = -13; - -// ERR_OUT_OF_RANGE: An argument is outside the valid range for this -// operation. -#[allow(unused)] -pub const ERR_OUT_OF_RANGE: zx_status_t = -14; - -// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for -// this operation. -#[allow(unused)] -pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15; - -// ======= Precondition or state errors ======= -// ERR_BAD_STATE: operation failed because the current state of the -// object does not allow it, or a precondition of the operation is -// not satisfied -#[allow(unused)] -pub const ERR_BAD_STATE: zx_status_t = -20; - -// ERR_TIMED_OUT: The time limit for the operation elapsed before -// the operation completed. -#[allow(unused)] -pub const ERR_TIMED_OUT: zx_status_t = -21; - -// ERR_SHOULD_WAIT: The operation cannot be performed currently but -// potentially could succeed if the caller waits for a prerequisite -// to be satisfied, for example waiting for a handle to be readable -// or writable. -// Example: Attempting to read from a message pipe that has no -// messages waiting but has an open remote will return ERR_SHOULD_WAIT. -// Attempting to read from a message pipe that has no messages waiting -// and has a closed remote end will return ERR_REMOTE_CLOSED. -#[allow(unused)] -pub const ERR_SHOULD_WAIT: zx_status_t = -22; - -// ERR_CANCELED: The in-progress operation (e.g., a wait) has been -// // canceled. -#[allow(unused)] -pub const ERR_CANCELED: zx_status_t = -23; - -// ERR_PEER_CLOSED: The operation failed because the remote end -// of the subject of the operation was closed. -#[allow(unused)] -pub const ERR_PEER_CLOSED: zx_status_t = -24; - -// ERR_NOT_FOUND: The requested entity is not found. -#[allow(unused)] -pub const ERR_NOT_FOUND: zx_status_t = -25; - -// ERR_ALREADY_EXISTS: An object with the specified identifier -// already exists. -// Example: Attempting to create a file when a file already exists -// with that name. -#[allow(unused)] -pub const ERR_ALREADY_EXISTS: zx_status_t = -26; - -// ERR_ALREADY_BOUND: The operation failed because the named entity -// is already owned or controlled by another entity. The operation -// could succeed later if the current owner releases the entity. -#[allow(unused)] -pub const ERR_ALREADY_BOUND: zx_status_t = -27; - -// ERR_UNAVAILABLE: The subject of the operation is currently unable -// to perform the operation. -// Note: This is used when there's no direct way for the caller to -// observe when the subject will be able to perform the operation -// and should thus retry. -#[allow(unused)] -pub const ERR_UNAVAILABLE: zx_status_t = -28; - -// ======= Permission check errors ======= -// ERR_ACCESS_DENIED: The caller did not have permission to perform -// the specified operation. -#[allow(unused)] -pub const ERR_ACCESS_DENIED: zx_status_t = -30; - -// ======= Input-output errors ======= -// ERR_IO: Otherwise unspecified error occurred during I/O. -#[allow(unused)] -pub const ERR_IO: zx_status_t = -40; - -// ERR_REFUSED: The entity the I/O operation is being performed on -// rejected the operation. -// Example: an I2C device NAK'ing a transaction or a disk controller -// rejecting an invalid command. -#[allow(unused)] -pub const ERR_IO_REFUSED: zx_status_t = -41; - -// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity -// check and is possibly corrupted. -// Example: CRC or Parity error. -#[allow(unused)] -pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42; - -// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable -// and may be permanently lost. -// Example: A disk block is irrecoverably damaged. -#[allow(unused)] -pub const ERR_IO_DATA_LOSS: zx_status_t = -43; - -// Filesystem specific errors -#[allow(unused)] -pub const ERR_BAD_PATH: zx_status_t = -50; -#[allow(unused)] -pub const ERR_NOT_DIR: zx_status_t = -51; -#[allow(unused)] -pub const ERR_NOT_FILE: zx_status_t = -52; -// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit. -#[allow(unused)] -pub const ERR_FILE_BIG: zx_status_t = -53; -// ERR_NO_SPACE: Filesystem or device space is exhausted. -#[allow(unused)] -pub const ERR_NO_SPACE: zx_status_t = -54; +pub fn zx_cvt(t: T) -> io::Result +where + T: TryInto + Copy, +{ + if let Ok(status) = TryInto::try_into(t) { + if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) } + } else { + Err(io::Error::last_os_error()) + } +} diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index 8d89163c42ce..c23278bdf5e5 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -254,67 +254,29 @@ pub fn futex_wake_all(futex: &Atomic) { unsafe { emscripten_futex_wake(futex, i32::MAX) }; } -#[cfg(target_os = "fuchsia")] -pub mod zircon { - pub type zx_futex_t = crate::sync::atomic::Atomic; - pub type zx_handle_t = u32; - pub type zx_status_t = i32; - pub type zx_time_t = i64; - - pub const ZX_HANDLE_INVALID: zx_handle_t = 0; - - pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX; - - pub const ZX_OK: zx_status_t = 0; - pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10; - pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11; - pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12; - pub const ZX_ERR_BAD_STATE: zx_status_t = -20; - pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; - - unsafe extern "C" { - pub fn zx_clock_get_monotonic() -> zx_time_t; - pub fn zx_futex_wait( - value_ptr: *const zx_futex_t, - current_value: zx_futex_t, - new_futex_owner: zx_handle_t, - deadline: zx_time_t, - ) -> zx_status_t; - pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t; - pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t; - pub fn zx_thread_self() -> zx_handle_t; - } -} - #[cfg(target_os = "fuchsia")] pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) -> bool { + use super::fuchsia::*; + // Sleep forever if the timeout is longer than fits in a i64. let deadline = timeout - .and_then(|d| { - i64::try_from(d.as_nanos()) - .ok()? - .checked_add(unsafe { zircon::zx_clock_get_monotonic() }) - }) - .unwrap_or(zircon::ZX_TIME_INFINITE); + .and_then(|d| i64::try_from(d.as_nanos()).ok()?.checked_add(zx_clock_get_monotonic())) + .unwrap_or(ZX_TIME_INFINITE); unsafe { - zircon::zx_futex_wait( - futex, - core::sync::atomic::AtomicU32::new(expected), - zircon::ZX_HANDLE_INVALID, - deadline, - ) != zircon::ZX_ERR_TIMED_OUT + zx_futex_wait(futex, zx_futex_t::new(expected), ZX_HANDLE_INVALID, deadline) + != ZX_ERR_TIMED_OUT } } // Fuchsia doesn't tell us how many threads are woken up, so this always returns false. #[cfg(target_os = "fuchsia")] pub fn futex_wake(futex: &Atomic) -> bool { - unsafe { zircon::zx_futex_wake(futex, 1) }; + unsafe { super::fuchsia::zx_futex_wake(futex, 1) }; false } #[cfg(target_os = "fuchsia")] pub fn futex_wake_all(futex: &Atomic) { - unsafe { zircon::zx_futex_wake(futex, u32::MAX) }; + unsafe { super::fuchsia::zx_futex_wake(futex, u32::MAX) }; } diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 4cdc2eaf0e53..afda7c65e108 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -22,23 +22,6 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024; #[cfg(any(target_os = "espidf", target_os = "nuttx"))] pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF/NuttX menuconfig system should be used -#[cfg(target_os = "fuchsia")] -mod zircon { - type zx_handle_t = u32; - type zx_status_t = i32; - pub const ZX_PROP_NAME: u32 = 3; - - unsafe extern "C" { - pub fn zx_object_set_property( - handle: zx_handle_t, - property: u32, - value: *const libc::c_void, - value_size: libc::size_t, - ) -> zx_status_t; - pub fn zx_thread_self() -> zx_handle_t; - } -} - pub struct Thread { id: libc::pthread_t, } @@ -216,7 +199,7 @@ impl Thread { #[cfg(target_os = "fuchsia")] pub fn set_name(name: &CStr) { - use self::zircon::*; + use super::fuchsia::*; unsafe { zx_object_set_property( zx_thread_self(), diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs index 0de32ecffd4b..eb62bbd808e8 100644 --- a/library/std/src/sys/process/unix/fuchsia.rs +++ b/library/std/src/sys/process/unix/fuchsia.rs @@ -81,7 +81,7 @@ impl Command { let mut handle = ZX_HANDLE_INVALID; let status = fdio_fd_clone(target_fd, &mut handle); - if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED { + if status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_NOT_SUPPORTED { // This descriptor is closed; skip it rather than generating an // error. return Ok(Default::default()); @@ -197,7 +197,7 @@ impl Process { zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut()); match status { 0 => {} // Success - x if x == ERR_TIMED_OUT => { + x if x == ZX_ERR_TIMED_OUT => { return Ok(None); } _ => { diff --git a/library/std/src/sys/sync/mutex/fuchsia.rs b/library/std/src/sys/sync/mutex/fuchsia.rs index 3d388a4564a3..cbb1926530f5 100644 --- a/library/std/src/sys/sync/mutex/fuchsia.rs +++ b/library/std/src/sys/sync/mutex/fuchsia.rs @@ -39,7 +39,7 @@ use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; use crate::sync::atomic::{Atomic, AtomicU32}; -use crate::sys::futex::zircon::{ +use crate::sys::fuchsia::{ ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE, ZX_OK, ZX_TIME_INFINITE, zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_thread_self, @@ -83,13 +83,13 @@ impl Mutex { #[inline] pub fn try_lock(&self) -> bool { - let thread_self = unsafe { zx_thread_self() }; + let thread_self = zx_thread_self(); self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok() } #[inline] pub fn lock(&self) { - let thread_self = unsafe { zx_thread_self() }; + let thread_self = zx_thread_self(); if let Err(state) = self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed) { From a8f7fd1d2633ce5196bd5a00882cb03fd6046067 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 5 May 2025 10:35:46 +0000 Subject: [PATCH 141/262] update `cc_detect` tests Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/cc_detect/tests.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs index b4a1b52dd230..43d61ce02c5a 100644 --- a/src/bootstrap/src/utils/cc_detect/tests.rs +++ b/src/bootstrap/src/utils/cc_detect/tests.rs @@ -181,7 +181,7 @@ fn test_language_clang() { #[test] fn test_new_cc_build() { - let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); let cfg = new_cc_build(&build, target.clone()); let compiler = cfg.get_compiler(); @@ -190,7 +190,7 @@ fn test_new_cc_build() { #[test] fn test_default_compiler_wasi() { - let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target = TargetSelection::from_user("wasm32-wasi"); let wasi_sdk = PathBuf::from("/wasi-sdk"); // SAFETY: bootstrap tests run on a single thread @@ -215,7 +215,7 @@ fn test_default_compiler_wasi() { #[test] fn test_default_compiler_fallback() { - let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); let mut cfg = cc::Build::new(); let result = default_compiler(&mut cfg, Language::C, target, &build); @@ -224,7 +224,7 @@ fn test_default_compiler_fallback() { #[test] fn test_find_target_with_config() { - let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); let mut target_config = Target::default(); target_config.cc = Some(PathBuf::from("dummy-cc")); @@ -249,7 +249,7 @@ fn test_find_target_with_config() { #[test] fn test_find_target_without_config() { - let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target = TargetSelection::from_user("x86_64-unknown-linux-gnu"); build.config.target_config.clear(); find_target(&build, target.clone()); @@ -262,7 +262,7 @@ fn test_find_target_without_config() { #[test] fn test_find() { - let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); + let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) }); let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu"); let target2 = TargetSelection::from_user("x86_64-unknown-openbsd"); build.targets.push(target1.clone()); From fe98130e0ff87ef16170b4f03afd5c7bbb7da573 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 15 Apr 2025 22:09:10 -0700 Subject: [PATCH 142/262] match ergonomics for string and byte string literal patterns --- compiler/rustc_hir_typeck/src/pat.rs | 89 ++++++++++++++----- .../const-pats-do-not-mislead-inference.rs | 48 ++++++++++ ...ats-do-not-mislead-inference.stable.stderr | 44 +++++++++ tests/ui/pattern/deref-patterns/needs-gate.rs | 17 ++++ .../pattern/deref-patterns/needs-gate.stderr | 32 ++++++- tests/ui/pattern/deref-patterns/strings.rs | 20 +++-- .../ui/pattern/deref-patterns/typeck_fail.rs | 13 --- .../pattern/deref-patterns/typeck_fail.stderr | 23 +---- 8 files changed, 223 insertions(+), 63 deletions(-) create mode 100644 tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs create mode 100644 tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ea335c7a4a7b..c96ad0749a1e 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -177,16 +177,20 @@ enum PeelKind { /// Only peel reference types. This is used for explicit `deref!(_)` patterns, which dereference /// any number of `&`/`&mut` references, plus a single smart pointer. ExplicitDerefPat, - /// Implicitly peel any number of references, and if `deref_patterns` is enabled, smart pointer - /// ADTs. In order to peel only as much as necessary for the pattern to match, the `until_adt` - /// field contains the ADT def that the pattern is a constructor for, if applicable, so that we - /// don't peel it. See [`ResolvedPat`] for more information. - Implicit { until_adt: Option }, + /// Implicitly peel references, and if `deref_patterns` is enabled, smart pointer ADTs. + Implicit { + /// The ADT the pattern is a constructor for, if applicable, so that we don't peel it. See + /// [`ResolvedPat`] for more information. + until_adt: Option, + /// The number of references at the head of the pattern's type, so we can leave that many + /// untouched. This is `1` for string literals, and `0` for most patterns. + pat_ref_layers: usize, + }, } impl AdjustMode { const fn peel_until_adt(opt_adt_def: Option) -> AdjustMode { - AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: opt_adt_def } } + AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: opt_adt_def, pat_ref_layers: 0 } } } const fn peel_all() -> AdjustMode { AdjustMode::peel_until_adt(None) @@ -488,9 +492,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 + _ if let AdjustMode::Peel { kind: peel_kind } = adjust_mode && pat.default_binding_modes - && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() => + && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() + && self.should_peel_ref(peel_kind, expected) => { debug!("inspecting {:?}", expected); @@ -665,21 +670,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // String and byte-string literals result in types `&str` and `&[u8]` respectively. // All other literals result in non-reference types. - // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`. - // - // Call `resolve_vars_if_possible` here for inline const blocks. - PatKind::Expr(lt) => match self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)).kind() { - ty::Ref(..) => AdjustMode::Pass, - _ => { - // Path patterns have already been handled, and inline const blocks currently - // aren't possible to write, so any handling for them would be untested. - if cfg!(debug_assertions) - && self.tcx.features().deref_patterns() - && !matches!(lt.kind, PatExprKind::Lit { .. }) - { - span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind); + // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}` unless + // `deref_patterns` is enabled. + PatKind::Expr(lt) => { + // Path patterns have already been handled, and inline const blocks currently + // aren't possible to write, so any handling for them would be untested. + if cfg!(debug_assertions) + && self.tcx.features().deref_patterns() + && !matches!(lt.kind, PatExprKind::Lit { .. }) + { + span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind); + } + // Call `resolve_vars_if_possible` here for inline const blocks. + let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)); + // If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`. + if self.tcx.features().deref_patterns() { + let mut peeled_ty = lit_ty; + let mut pat_ref_layers = 0; + while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() { + // We rely on references at the head of constants being immutable. + debug_assert!(mutbl.is_not()); + pat_ref_layers += 1; + peeled_ty = inner_ty; } - AdjustMode::peel_all() + AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } } + } else { + if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() } } }, @@ -705,6 +721,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Assuming `expected` is a reference type, determine whether to peel it before matching. + fn should_peel_ref(&self, peel_kind: PeelKind, mut expected: Ty<'tcx>) -> bool { + debug_assert!(expected.is_ref()); + let pat_ref_layers = match peel_kind { + PeelKind::ExplicitDerefPat => 0, + PeelKind::Implicit { pat_ref_layers, .. } => pat_ref_layers, + }; + + // Most patterns don't have reference types, so we'll want to peel all references from the + // scrutinee before matching. To optimize for the common case, return early. + if pat_ref_layers == 0 { + return true; + } + debug_assert!( + self.tcx.features().deref_patterns(), + "Peeling for patterns with reference types is gated by `deref_patterns`." + ); + + // If the pattern has as many or more layers of reference as the expected type, we can match + // without peeling more, *unless* we find a smart pointer that we also need to peel. + // TODO: always peel `&mut` + let mut expected_ref_layers = 0; + while let ty::Ref(_, inner_ty, _) = *expected.kind() { + expected_ref_layers += 1; + expected = inner_ty; + } + pat_ref_layers < expected_ref_layers || self.should_peel_smart_pointer(peel_kind, expected) + } + /// Determine whether `expected` is a smart pointer type that should be peeled before matching. fn should_peel_smart_pointer(&self, peel_kind: PeelKind, expected: Ty<'tcx>) -> bool { // Explicit `deref!(_)` patterns match against smart pointers; don't peel in that case. diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs new file mode 100644 index 000000000000..437c2ef7c651 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs @@ -0,0 +1,48 @@ +//@ revisions: stable deref_patterns +//@[deref_patterns] check-pass +//! `deref_patterns` allows string and byte string literal patterns to implicitly peel references +//! and smart pointers from the scrutinee before matching. Since strings and byte strings themselves +//! have reference types, we need to make sure we don't peel too much. By leaving the type of the +//! match scrutinee partially uninferred, these tests make sure we only peel as much as needed in +//! order to match. In particular, when peeling isn't needed, the results should be the same was +//! we'd get without `deref_patterns` enabled. + +#![cfg_attr(deref_patterns, feature(deref_patterns))] +#![cfg_attr(deref_patterns, expect(incomplete_features))] + +fn uninferred() -> T { unimplemented!() } + +// Assert type equality without allowing coercions. +trait Is {} +impl Is for T {} +fn has_type(_: impl Is) {} + +fn main() { + // We don't need to peel anything to unify the type of `x` with `&str`, so `x: &str`. + let x = uninferred(); + if let "..." = x {} + has_type::<&str>(x); + + // We don't need to peel anything to unify the type of `&x` with `&[u8; 3]`, so `x: [u8; 3]`. + let x = uninferred(); + if let b"..." = &x {} + has_type::<[u8; 3]>(x); + + // Peeling a single `&` lets us unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`. + let x = uninferred(); + if let b"..." = &&x {} + //[stable]~^ ERROR: mismatched types + has_type::<[u8; 3]>(x); + + // We have to peel both the `&` and the box before unifying the type of `x` with `&str`. + let x = uninferred(); + if let "..." = &Box::new(x) {} + //[stable]~^ ERROR mismatched types + has_type::<&str>(x); + + // After peeling the box, we can unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`. + let x = uninferred(); + if let b"..." = Box::new(&x) {} + //[stable]~^ ERROR mismatched types + has_type::<[u8; 3]>(x); +} diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr new file mode 100644 index 000000000000..9dcb91311846 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr @@ -0,0 +1,44 @@ +error[E0308]: mismatched types + --> $DIR/const-pats-do-not-mislead-inference.rs:33:12 + | +LL | if let b"..." = &&x {} + | ^^^^^^ --- this expression has type `&&_` + | | + | expected `&&_`, found `&[u8; 3]` + | + = note: expected reference `&&_` + found reference `&'static [u8; 3]` + +error[E0308]: mismatched types + --> $DIR/const-pats-do-not-mislead-inference.rs:39:12 + | +LL | if let "..." = &Box::new(x) {} + | ^^^^^ ------------ this expression has type `&Box<_>` + | | + | expected `&Box<_>`, found `&str` + | + = note: expected reference `&Box<_>` + found reference `&'static str` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | if let "..." = &*Box::new(x) {} + | + + +error[E0308]: mismatched types + --> $DIR/const-pats-do-not-mislead-inference.rs:45:12 + | +LL | if let b"..." = Box::new(&x) {} + | ^^^^^^ ------------ this expression has type `Box<&_>` + | | + | expected `Box<&_>`, found `&[u8; 3]` + | + = note: expected struct `Box<&_>` + found reference `&'static [u8; 3]` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | if let b"..." = *Box::new(&x) {} + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/deref-patterns/needs-gate.rs b/tests/ui/pattern/deref-patterns/needs-gate.rs index 7944744ee839..5dcf69a92d3c 100644 --- a/tests/ui/pattern/deref-patterns/needs-gate.rs +++ b/tests/ui/pattern/deref-patterns/needs-gate.rs @@ -29,4 +29,21 @@ fn main() { //~^ ERROR: mismatched types _ => {} } + + // `deref_patterns` allows string and byte string patterns to implicitly peel references. + match &"str" { + "str" => {} + //~^ ERROR: mismatched types + _ => {} + } + match &b"str" { + b"str" => {} + //~^ ERROR: mismatched types + _ => {} + } + match "str".to_owned() { + "str" => {} + //~^ ERROR: mismatched types + _ => {} + } } diff --git a/tests/ui/pattern/deref-patterns/needs-gate.stderr b/tests/ui/pattern/deref-patterns/needs-gate.stderr index e886ca980558..55e1fa826e86 100644 --- a/tests/ui/pattern/deref-patterns/needs-gate.stderr +++ b/tests/ui/pattern/deref-patterns/needs-gate.stderr @@ -47,7 +47,37 @@ LL | match *(b"test" as &[u8]) { LL | b"test" => {} | ^^^^^^^ expected `[u8]`, found `&[u8; 4]` -error: aborting due to 5 previous errors +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:35:9 + | +LL | match &"str" { + | ------ this expression has type `&&str` +LL | "str" => {} + | ^^^^^ expected `&&str`, found `&str` + | + = note: expected reference `&&_` + found reference `&'static _` + +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:40:9 + | +LL | match &b"str" { + | ------- this expression has type `&&[u8; 3]` +LL | b"str" => {} + | ^^^^^^ expected `&&[u8; 3]`, found `&[u8; 3]` + | + = note: expected reference `&&_` + found reference `&'static _` + +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:45:9 + | +LL | match "str".to_owned() { + | ---------------- this expression has type `String` +LL | "str" => {} + | ^^^^^ expected `String`, found `&str` + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/deref-patterns/strings.rs b/tests/ui/pattern/deref-patterns/strings.rs index 536e943b3f67..7d571c81e91c 100644 --- a/tests/ui/pattern/deref-patterns/strings.rs +++ b/tests/ui/pattern/deref-patterns/strings.rs @@ -14,10 +14,18 @@ fn main() { }; assert_eq!(test_actual, test_expect); - // Test string literals in explicit `deref!(_)` patterns. + // Test string literals in deref patterns. let test_actual = match test_in.to_string() { deref!("zero") => 0, - deref!("one") => 1, + "one" => 1, + _ => 2, + }; + assert_eq!(test_actual, test_expect); + + // Test peeling references in addition to smart pointers. + let test_actual = match &test_in.to_string() { + deref!("zero") => 0, + "one" => 1, _ => 2, }; assert_eq!(test_actual, test_expect); @@ -47,18 +55,18 @@ fn main() { }; assert_eq!(test_actual, test_expect); - // Test byte string literals used as arrays in explicit `deref!(_)` patterns. + // Test byte string literals used as arrays in deref patterns. let test_actual = match Box::new(*test_in) { deref!(b"0") => 0, - deref!(b"1") => 1, + b"1" => 1, _ => 2, }; assert_eq!(test_actual, test_expect); - // Test byte string literals used as slices in explicit `deref!(_)` patterns. + // Test byte string literals used as slices in deref patterns. let test_actual = match test_in.to_vec() { deref!(b"0") => 0, - deref!(b"1") => 1, + b"1" => 1, _ => 2, }; assert_eq!(test_actual, test_expect); diff --git a/tests/ui/pattern/deref-patterns/typeck_fail.rs b/tests/ui/pattern/deref-patterns/typeck_fail.rs index 52d84f7a34de..6ae87bb7bc36 100644 --- a/tests/ui/pattern/deref-patterns/typeck_fail.rs +++ b/tests/ui/pattern/deref-patterns/typeck_fail.rs @@ -2,19 +2,6 @@ #![allow(incomplete_features)] fn main() { - // FIXME(deref_patterns): fails to typecheck because string literal patterns don't peel - // references from the scrutinee. - match "foo".to_string() { - "foo" => {} - //~^ ERROR: mismatched types - _ => {} - } - match &"foo".to_string() { - "foo" => {} - //~^ ERROR: mismatched types - _ => {} - } - // Make sure we don't try implicitly dereferncing any ADT. match Some(0) { Ok(0) => {} diff --git a/tests/ui/pattern/deref-patterns/typeck_fail.stderr b/tests/ui/pattern/deref-patterns/typeck_fail.stderr index e87528c1c51a..fc29caac5630 100644 --- a/tests/ui/pattern/deref-patterns/typeck_fail.stderr +++ b/tests/ui/pattern/deref-patterns/typeck_fail.stderr @@ -1,24 +1,5 @@ error[E0308]: mismatched types - --> $DIR/typeck_fail.rs:8:9 - | -LL | match "foo".to_string() { - | ----------------- this expression has type `String` -LL | "foo" => {} - | ^^^^^ expected `String`, found `&str` - -error[E0308]: mismatched types - --> $DIR/typeck_fail.rs:13:9 - | -LL | match &"foo".to_string() { - | ------------------ this expression has type `&String` -LL | "foo" => {} - | ^^^^^ expected `&String`, found `&str` - | - = note: expected reference `&String` - found reference `&'static str` - -error[E0308]: mismatched types - --> $DIR/typeck_fail.rs:20:9 + --> $DIR/typeck_fail.rs:7:9 | LL | match Some(0) { | ------- this expression has type `Option<{integer}>` @@ -28,6 +9,6 @@ LL | Ok(0) => {} = note: expected enum `Option<{integer}>` found enum `Result<_, _>` -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. From 17bb4bbc86c2078e8ca09e2fdf6fd380094be6d6 Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 5 May 2025 03:40:37 -0700 Subject: [PATCH 143/262] always peel `&mut`, to allow matching on `&mut str` --- compiler/rustc_hir_typeck/src/pat.rs | 13 ++++-- .../deref-patterns/byte-string-type-errors.rs | 19 +++++++++ .../byte-string-type-errors.stderr | 40 ++++++++++++++++++- .../const-pats-do-not-mislead-inference.rs | 6 +++ ...ats-do-not-mislead-inference.stable.stderr | 13 +++++- tests/ui/pattern/deref-patterns/needs-gate.rs | 9 +++++ .../pattern/deref-patterns/needs-gate.stderr | 35 +++++++++++++++- tests/ui/pattern/deref-patterns/strings.rs | 24 +++++++++++ 8 files changed, 153 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c96ad0749a1e..f9502153afdc 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -740,10 +740,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // If the pattern has as many or more layers of reference as the expected type, we can match - // without peeling more, *unless* we find a smart pointer that we also need to peel. - // TODO: always peel `&mut` + // without peeling more, unless we find a smart pointer or `&mut` that we also need to peel. + // We don't treat `&` and `&mut` as interchangeable, but by peeling `&mut`s before matching, + // we can still, e.g., match on a `&mut str` with a string literal pattern. This is because + // string literal patterns may be used where `str` is expected. let mut expected_ref_layers = 0; - while let ty::Ref(_, inner_ty, _) = *expected.kind() { + while let ty::Ref(_, inner_ty, mutbl) = *expected.kind() { + if mutbl.is_mut() { + // Mutable references can't be in the final value of constants, thus they can't be + // at the head of their types, thus we should always peel `&mut`. + return true; + } expected_ref_layers += 1; expected = inner_ty; } diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs index 64acc4748afd..fdcc6cb46111 100644 --- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs +++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs @@ -33,4 +33,23 @@ fn main() { if let b"test" = *b"this array is too long" {} //~^ ERROR mismatched types //~| NOTE expected an array with a size of 22, found one with a size of 4 + + // Test matching on `&mut T`: we peel the `&mut` before applying the usual special cases. + // No special cases apply to `()`, so the "found" type is the type of the literal. + if let b"test" = &mut () {} + //~^ ERROR mismatched types + //~| NOTE expected `()`, found `&[u8; 4]` + + // If the pointee is an array or slice, the usual special cases will apply to the "found" type: + if let b"test" = &mut [] as &mut [i8] {} + //~^ ERROR mismatched type + //~| NOTE expected `[i8]`, found `[u8]` + + if let b"test" = &mut [()] {} + //~^ ERROR mismatched types + //~| NOTE expected `[(); 1]`, found `[u8; 4]` + + if let b"test" = &mut *b"this array is too long" {} + //~^ ERROR mismatched type + //~| NOTE expected an array with a size of 22, found one with a size of 4 } diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr index 0317b7209e16..046682004be7 100644 --- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr +++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr @@ -47,6 +47,44 @@ LL | if let b"test" = *b"this array is too long" {} | | | expected an array with a size of 22, found one with a size of 4 -error: aborting due to 5 previous errors +error[E0308]: mismatched types + --> $DIR/byte-string-type-errors.rs:39:12 + | +LL | if let b"test" = &mut () {} + | ^^^^^^^ ------- this expression has type `&mut ()` + | | + | expected `()`, found `&[u8; 4]` + +error[E0308]: mismatched types + --> $DIR/byte-string-type-errors.rs:44:12 + | +LL | if let b"test" = &mut [] as &mut [i8] {} + | ^^^^^^^ -------------------- this expression has type `&mut [i8]` + | | + | expected `[i8]`, found `[u8]` + | + = note: expected slice `[i8]` + found slice `[u8]` + +error[E0308]: mismatched types + --> $DIR/byte-string-type-errors.rs:48:12 + | +LL | if let b"test" = &mut [()] {} + | ^^^^^^^ --------- this expression has type `&mut [(); 1]` + | | + | expected `[(); 1]`, found `[u8; 4]` + | + = note: expected array `[(); 1]` + found array `[u8; 4]` + +error[E0308]: mismatched types + --> $DIR/byte-string-type-errors.rs:52:12 + | +LL | if let b"test" = &mut *b"this array is too long" {} + | ^^^^^^^ ------------------------------- this expression has type `&mut [u8; 22]` + | | + | expected an array with a size of 22, found one with a size of 4 + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs index 437c2ef7c651..3a2531f4b95e 100644 --- a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs +++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs @@ -45,4 +45,10 @@ fn main() { if let b"..." = Box::new(&x) {} //[stable]~^ ERROR mismatched types has_type::<[u8; 3]>(x); + + // `&` and `&mut` aren't interchangeable: `&mut`s need to be peeled before unifying, like boxes: + let mut x = uninferred(); + if let "..." = &mut x {} + //[stable]~^ ERROR mismatched types + has_type::<&str>(x); } diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr index 9dcb91311846..61079718c5d5 100644 --- a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr +++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr @@ -39,6 +39,17 @@ help: consider dereferencing to access the inner value using the Deref trait LL | if let b"..." = *Box::new(&x) {} | + -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/const-pats-do-not-mislead-inference.rs:51:12 + | +LL | if let "..." = &mut x {} + | ^^^^^ ------ this expression has type `&mut _` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut _` + found reference `&'static str` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/deref-patterns/needs-gate.rs b/tests/ui/pattern/deref-patterns/needs-gate.rs index 5dcf69a92d3c..953051f7b04b 100644 --- a/tests/ui/pattern/deref-patterns/needs-gate.rs +++ b/tests/ui/pattern/deref-patterns/needs-gate.rs @@ -46,4 +46,13 @@ fn main() { //~^ ERROR: mismatched types _ => {} } + + // `deref_patterns` allows string and byte string patterns to match on mutable references. + // See also `tests/ui/pattern/byte-string-mutability-mismatch.rs`. + if let "str" = &mut *"str".to_string() {} + //~^ ERROR mismatched types + if let b"str" = &mut b"str".clone() {} + //~^ ERROR mismatched types + if let b"str" = &mut b"str".clone()[..] {} + //~^ ERROR mismatched types } diff --git a/tests/ui/pattern/deref-patterns/needs-gate.stderr b/tests/ui/pattern/deref-patterns/needs-gate.stderr index 55e1fa826e86..3d938a7e23fc 100644 --- a/tests/ui/pattern/deref-patterns/needs-gate.stderr +++ b/tests/ui/pattern/deref-patterns/needs-gate.stderr @@ -77,7 +77,40 @@ LL | match "str".to_owned() { LL | "str" => {} | ^^^^^ expected `String`, found `&str` -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:52:12 + | +LL | if let "str" = &mut *"str".to_string() {} + | ^^^^^ ----------------------- this expression has type `&mut str` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut _` + found reference `&'static _` + +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:54:12 + | +LL | if let b"str" = &mut b"str".clone() {} + | ^^^^^^ ------------------- this expression has type `&mut [u8; 3]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut _` + found reference `&'static _` + +error[E0308]: mismatched types + --> $DIR/needs-gate.rs:56:12 + | +LL | if let b"str" = &mut b"str".clone()[..] {} + | ^^^^^^ ----------------------- this expression has type `&mut [u8]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut _` + found reference `&'static _` + +error: aborting due to 11 previous errors Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/deref-patterns/strings.rs b/tests/ui/pattern/deref-patterns/strings.rs index 7d571c81e91c..fac15a9aee3d 100644 --- a/tests/ui/pattern/deref-patterns/strings.rs +++ b/tests/ui/pattern/deref-patterns/strings.rs @@ -14,6 +14,14 @@ fn main() { }; assert_eq!(test_actual, test_expect); + // Test matching on `&mut str`. + let test_actual = match &mut *test_in.to_string() { + "zero" => 0, + "one" => 1, + _ => 2, + }; + assert_eq!(test_actual, test_expect); + // Test string literals in deref patterns. let test_actual = match test_in.to_string() { deref!("zero") => 0, @@ -55,6 +63,22 @@ fn main() { }; assert_eq!(test_actual, test_expect); + // Test matching on `&mut [u8; N]`. + let test_actual = match &mut test_in.clone() { + b"0" => 0, + b"1" => 1, + _ => 2, + }; + assert_eq!(test_actual, test_expect); + + // Test matching on `&mut [u8]`. + let test_actual = match &mut test_in.clone()[..] { + b"0" => 0, + b"1" => 1, + _ => 2, + }; + assert_eq!(test_actual, test_expect); + // Test byte string literals used as arrays in deref patterns. let test_actual = match Box::new(*test_in) { deref!(b"0") => 0, From 7e4f6d3a30f22aa86ffbb3a73969646e42952525 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 4 May 2025 20:36:50 -0700 Subject: [PATCH 144/262] update unstable book --- .../src/language-features/deref-patterns.md | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md index 0cc7106da48f..fb6df290cc12 100644 --- a/src/doc/unstable-book/src/language-features/deref-patterns.md +++ b/src/doc/unstable-book/src/language-features/deref-patterns.md @@ -65,15 +65,26 @@ let deref!(x) = Box::new(NoCopy) else { unreachable!() }; drop::(x); ``` -Additionally, when `deref_patterns` is enabled, string literal patterns may be written where `str` -is expected. Likewise, byte string literal patterns may be written where `[u8]` or `[u8; _]` is -expected. This lets them be used in `deref!(_)` patterns: +Additionally, `deref_patterns` implements changes to string and byte string literal patterns, +allowing then to be used in deref patterns: ```rust # #![feature(deref_patterns)] # #![allow(incomplete_features)] -match ("test".to_string(), b"test".to_vec()) { - (deref!("test"), deref!(b"test")) => {} +match ("test".to_string(), Box::from("test"), b"test".to_vec()) { + ("test", "test", b"test") => {} + _ => panic!(), +} + +// This works through multiple layers of reference and smart pointer: +match (&Box::new(&"test".to_string()), &&&"test") { + ("test", "test") => {} + _ => panic!(), +} + +// `deref!("...")` syntax may also be used: +match "test".to_string() { + deref!("test") => {} _ => panic!(), } @@ -82,10 +93,16 @@ match *"test" { "test" => {} _ => panic!(), } +match *b"test" { + b"test" => {} + _ => panic!(), +} +match *(b"test" as &[u8]) { + b"test" => {} + _ => panic!(), +} ``` -Implicit deref pattern syntax is not yet supported for string or byte string literals. - [`box_patterns`]: ./box-patterns.md [`string_deref_patterns`]: ./string-deref-patterns.md [smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors From 4b58c5034a59f58b9ba1a713a667b4d9ffc1df34 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 5 May 2025 12:34:22 +0000 Subject: [PATCH 145/262] Make -Zfixed-x18 into a target modifier --- compiler/rustc_session/src/options.rs | 2 +- .../ui/target_modifiers/auxiliary/fixed_x18.rs | 7 +++++++ ...incompatible_fixedx18.error_generated.stderr | 13 +++++++++++++ .../target_modifiers/incompatible_fixedx18.rs | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/ui/target_modifiers/auxiliary/fixed_x18.rs create mode 100644 tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr create mode 100644 tests/ui/target_modifiers/incompatible_fixedx18.rs diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 5f4695fb1841..c3d922fc9c5e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2208,7 +2208,7 @@ options! { fewer_names: Option = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), - fixed_x18: bool = (false, parse_bool, [TRACKED], + fixed_x18: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], "make the x18 register reserved on AArch64 (default: no)"), flatten_format_args: bool = (true, parse_bool, [TRACKED], "flatten nested format_args!() and literals into a simplified format_args!() call \ diff --git a/tests/ui/target_modifiers/auxiliary/fixed_x18.rs b/tests/ui/target_modifiers/auxiliary/fixed_x18.rs new file mode 100644 index 000000000000..32eff76ec54c --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/fixed_x18.rs @@ -0,0 +1,7 @@ +//@ no-prefer-dynamic +//@ compile-flags: --target aarch64-unknown-none -Zfixed-x18 +//@ needs-llvm-components: aarch64 + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr new file mode 100644 index 000000000000..096d7cb5f258 --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr @@ -0,0 +1,13 @@ +error: mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18` + --> $DIR/incompatible_fixedx18.rs:12:1 + | +LL | #![feature(no_core)] + | ^ + | + = help: the `-Zfixed-x18` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: unset `-Zfixed-x18` in this crate is incompatible with `-Zfixed-x18=` in dependency `fixed_x18` + = help: set `-Zfixed-x18=` in this crate or unset `-Zfixed-x18` in `fixed_x18` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=fixed-x18` to silence this error + +error: aborting due to 1 previous error + diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.rs b/tests/ui/target_modifiers/incompatible_fixedx18.rs new file mode 100644 index 000000000000..6c13984f608e --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_fixedx18.rs @@ -0,0 +1,17 @@ +//@ aux-build:fixed_x18.rs +//@ compile-flags: --target aarch64-unknown-none +//@ needs-llvm-components: aarch64 + +//@ revisions:allow_match allow_mismatch error_generated +//@[allow_match] compile-flags: -Zfixed-x18 +//@[allow_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=fixed-x18 +//@[error_generated] compile-flags: +//@[allow_mismatch] check-pass +//@[allow_match] check-pass + +#![feature(no_core)] +//[error_generated]~^ ERROR mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18` +#![crate_type = "rlib"] +#![no_core] + +extern crate fixed_x18; From 3a1ee645cad501e2fd766bbacea5654a795f352b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 27 Apr 2025 21:55:50 +0000 Subject: [PATCH 146/262] Resolve instance for SymFn in global/naked asm --- compiler/rustc_codegen_ssa/src/base.rs | 8 ++++- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 4 ++- tests/ui/asm/global-asm-mono-sym-fn.rs | 27 ++++++++++++++ tests/ui/asm/naked-asm-mono-sym-fn.rs | 35 +++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/ui/asm/global-asm-mono-sym-fn.rs create mode 100644 tests/ui/asm/naked-asm-mono-sym-fn.rs diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 89439e409378..775ab9071e74 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -457,7 +457,13 @@ where rustc_hir::InlineAsmOperand::SymFn { expr } => { let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => Instance::expect_resolve( + cx.tcx(), + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + expr.span, + ), _ => span_bug!(*op_sp, "asm sym is not a function"), }; diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 0301ef437c0d..d2a687359e0b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -95,7 +95,9 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL ); let instance = match mono_type.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => { + Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span) + } _ => bug!("asm sym is not a function"), }; diff --git a/tests/ui/asm/global-asm-mono-sym-fn.rs b/tests/ui/asm/global-asm-mono-sym-fn.rs new file mode 100644 index 000000000000..e584a98badb0 --- /dev/null +++ b/tests/ui/asm/global-asm-mono-sym-fn.rs @@ -0,0 +1,27 @@ +// Test that we're properly monomorphizing sym args in global asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64-unknown-linux-gnu +//@ build-pass + +#![no_main] + +use std::arch::global_asm; + +fn foo() { + loop {} +} + +trait Foo { + fn bar(); +} + +impl Foo for i32 { + fn bar() { + loop {} + } +} + +global_asm!(".global main", "main:", "call {}", sym ::bar); diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs new file mode 100644 index 000000000000..2bd554beacf8 --- /dev/null +++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs @@ -0,0 +1,35 @@ +// Regression test for . +// Test that we're properly monomorphizing sym args in naked asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64 +//@ build-pass + +trait T { + extern "C" fn t(); +} + +enum E {} + +impl T for E { + extern "C" fn t() { + println!("Const generic: {}", C); + } +} + +#[unsafe(naked)] +extern "C" fn foo() { + core::arch::naked_asm!( + "push rax", + "call {fn}", + "pop rax", + "ret", + fn = sym ::t, + ); +} + +fn main() { + foo::>(); +} From 833c212b81d38ce4fb10b7084549291052878822 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 28 Apr 2025 14:40:16 +0000 Subject: [PATCH 147/262] Rename Instance::new to Instance::new_raw and add a note that it is raw --- .../src/intrinsics/mod.rs | 2 +- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- .../src/coverageinfo/mapgen/unused.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- .../src/back/symbol_export.rs | 4 ++-- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_lint/src/foreign_modules.rs | 2 +- .../src/middle/exported_symbols.rs | 2 +- .../rustc_middle/src/mir/interpret/queries.rs | 6 +++--- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 18 +++++++++++++----- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- compiler/rustc_smir/src/rustc_smir/builder.rs | 2 +- compiler/rustc_symbol_mangling/src/test.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 10 +++++----- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- tests/ui/asm/naked-asm-mono-sym-fn.rs | 8 ++++---- 18 files changed, 41 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index d3f47ad72633..e866b8962551 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1282,7 +1282,7 @@ fn codegen_regular_intrinsic_call<'tcx>( intrinsic.name, ); } - return Err(Instance::new(instance.def_id(), instance.args)); + return Err(Instance::new_raw(instance.def_id(), instance.args)); } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index d22f4229e237..2ed5ec4381ed 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -399,7 +399,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } // Fall back to default body - _ => return Err(Instance::new(instance.def_id(), instance.args)), + _ => return Err(Instance::new_raw(instance.def_id(), instance.args)), }; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs index 68f60f169b5b..fe3a7a1580b5 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs @@ -157,7 +157,7 @@ fn make_dummy_instance<'tcx>(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> ty: let def_id = local_def_id.to_def_id(); // Make a dummy instance that fills in all generics with placeholders. - ty::Instance::new( + ty::Instance::new_raw( def_id, ty::GenericArgs::for_item(tcx, def_id, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ffeab59b05c3..bfaad8f2f1ef 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -613,7 +613,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => { debug!("unknown intrinsic '{}' -- falling back to default body", name); // Call the fallback body instead of generating the intrinsic code - return Err(ty::Instance::new(instance.def_id(), instance.args)); + return Err(ty::Instance::new_raw(instance.def_id(), instance.args)); } }; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 1bfdbc0b620e..5f0a0cf922af 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -612,7 +612,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( ExportedSymbol::Generic(def_id, args) => { rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, - Instance::new(def_id, args), + Instance::new_raw(def_id, args), instantiating_crate, ) } @@ -660,7 +660,7 @@ fn calling_convention_for_symbol<'tcx>( None } ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)), - ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)), + ExportedSymbol::Generic(def_id, args) => Some(Instance::new_raw(def_id, args)), // DropGlue always use the Rust calling convention and thus follow the target's default // symbol decoration scheme. ExportedSymbol::DropGlue(..) => None, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 309b8f2c7613..91dde13be550 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -216,7 +216,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { check::maybe_check_static_with_link_section(tcx, item_def_id); } DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { - let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); + let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 0494c78a7a97..d0668794198a 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -104,7 +104,7 @@ impl ClashingExternDeclarations { /// for the item, return its HirId without updating the set. fn insert(&mut self, tcx: TyCtxt<'_>, fi: hir::ForeignItemId) -> Option { let did = fi.owner_id.to_def_id(); - let instance = Instance::new(did, ty::List::identity_for_item(tcx, did)); + let instance = Instance::new_raw(did, ty::List::identity_for_item(tcx, did)); let name = Symbol::intern(tcx.symbol_name(instance).name); if let Some(&existing_id) = self.seen_decls.get(&name) { // Avoid updating the map with the new entry when we do find a collision. We want to diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 3c62017072e4..1d67d0fe3bbf 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -56,7 +56,7 @@ impl<'tcx> ExportedSymbol<'tcx> { match *self { ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, args) => { - tcx.symbol_name(ty::Instance::new(def_id, args)) + tcx.symbol_name(ty::Instance::new_raw(def_id, args)) } ExportedSymbol::DropGlue(ty) => { tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty)) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index e5d1dda3aa0f..4a5c42c721c1 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -23,7 +23,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); self.const_eval_global_id(typing_env, cid, DUMMY_SP) @@ -39,7 +39,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); let inputs = self.erase_regions(typing_env.as_query_input(cid)); @@ -209,7 +209,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self.tcx, def_id); - let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args)); + let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args)); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 6b413a7383a5..7243f87ee638 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -318,7 +318,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> { match *self { MonoItem::Fn(instance) => write!(f, "fn {instance}"), MonoItem::Static(def_id) => { - write!(f, "static {}", Instance::new(def_id, GenericArgs::empty())) + write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty())) } MonoItem::GlobalAsm(..) => write!(f, "global_asm"), } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6af9d4aae301..4981233cebe6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2481,7 +2481,7 @@ rustc_queries! { query resolve_instance_raw( key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { - desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } + desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } } query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index d660e7d0d602..0d99a1b51499 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -491,7 +491,15 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { } impl<'tcx> Instance<'tcx> { - pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { + /// Creates a new [`InstanceKind::Item`] from the `def_id` and `args`. + /// + /// Note that this item corresponds to the body of `def_id` directly, which + /// likely does not make sense for trait items which need to be resolved to an + /// implementation, and which may not even have a body themselves. Usages of + /// this function should probably use [`Instance::expect_resolve`], or if run + /// in a polymorphic environment or within a lint (that may encounter ambiguity) + /// [`Instance::try_resolve`] instead. + pub fn new_raw(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { assert!( !args.has_escaping_bound_vars(), "args of instance {def_id:?} has escaping bound vars: {args:?}" @@ -510,7 +518,7 @@ impl<'tcx> Instance<'tcx> { } }); - Instance::new(def_id, args) + Instance::new_raw(def_id, args) } #[inline] @@ -603,7 +611,7 @@ impl<'tcx> Instance<'tcx> { let type_length = type_length(args); if !tcx.type_length_limit().value_within_limit(type_length) { let (shrunk, written_to_path) = - shrunk_instance_name(tcx, Instance::new(def_id, args)); + shrunk_instance_name(tcx, Instance::new_raw(def_id, args)); let mut path = PathBuf::new(); let was_written = if let Some(path2) = written_to_path { path = path2; @@ -773,7 +781,7 @@ impl<'tcx> Instance<'tcx> { match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args), - _ => Instance::new(def_id, args), + _ => Instance::new_raw(def_id, args), } } @@ -899,7 +907,7 @@ impl<'tcx> Instance<'tcx> { // This is important for `Iterator`'s combinators, but also useful for // adding future default methods to `Future`, for instance. debug_assert!(tcx.defaultness(trait_item_id).has_value()); - Some(Instance::new(trait_item_id, rcvr_args)) + Some(Instance::new_raw(trait_item_id, rcvr_args)) } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1e3744e19f54..c6a81e60b2b5 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -931,7 +931,7 @@ fn visit_instance_use<'tcx>( // We explicitly skip this otherwise to ensure we get a linker error // if anyone tries to call this intrinsic and the codegen backend did not // override the implementation. - let instance = ty::Instance::new(instance.def_id(), instance.args); + let instance = ty::Instance::new_raw(instance.def_id(), instance.args); if tcx.should_codegen_locally(instance) { output.push(create_fn_mono_item(tcx, instance, source)); } @@ -1520,7 +1520,7 @@ impl<'v> RootCollector<'_, 'v> { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { - Instance::new(def_id, self.tcx.erase_regions(args)) + Instance::new_raw(def_id, self.tcx.erase_regions(args)) } _ => unreachable!(), }; diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index 64763b71d303..40e6d21c0637 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -22,7 +22,7 @@ impl<'tcx> BodyBuilder<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self { let instance = match instance.def { // To get the fallback body of an intrinsic, we need to convert it to an item. - ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args), + ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args), _ => instance, }; BodyBuilder { tcx, instance } diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index ddeeadff13d1..0c6d1495e39c 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -56,7 +56,7 @@ impl SymbolNamesTest<'_> { // some subset. for attr in tcx.get_attrs(def_id, SYMBOL_NAME) { let def_id = def_id.to_def_id(); - let instance = Instance::new( + let instance = Instance::new_raw( def_id, tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)), ); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index da83566dad02..166e8f193429 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -235,7 +235,7 @@ fn resolve_associated_item<'tcx>( tcx.ensure_ok().compare_impl_item(leaf_def_item)?; } - Some(ty::Instance::new(leaf_def.item.def_id, args)) + Some(ty::Instance::new_raw(leaf_def.item.def_id, args)) } traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => { let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args); @@ -280,7 +280,7 @@ fn resolve_associated_item<'tcx>( // Use the default `fn clone_from` from `trait Clone`. let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) { if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) { @@ -329,7 +329,7 @@ fn resolve_associated_item<'tcx>( // sync with the built-in trait implementations (since all of the // implementations return `FnOnce::Output`). if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } else { Some(Instance { def: ty::InstanceKind::ConstructCoroutineInClosureShim { @@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>( args, }) } else { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } } ty::Closure(closure_def_id, args) => { @@ -381,7 +381,7 @@ fn resolve_associated_item<'tcx>( let name = tcx.item_name(trait_item_id); assert_eq!(name, sym::transmute); let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 63859c0396e4..6d3e77b6b6e9 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -263,7 +263,7 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None, diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs index 2bd554beacf8..948c290c0b4f 100644 --- a/tests/ui/asm/naked-asm-mono-sym-fn.rs +++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs @@ -7,26 +7,26 @@ //@ only-x86_64 //@ build-pass -trait T { +trait Tr { extern "C" fn t(); } enum E {} -impl T for E { +impl Tr for E { extern "C" fn t() { println!("Const generic: {}", C); } } #[unsafe(naked)] -extern "C" fn foo() { +extern "C" fn foo() { core::arch::naked_asm!( "push rax", "call {fn}", "pop rax", "ret", - fn = sym ::t, + fn = sym ::t, ); } From 2426dbcde20d1c34a50ff1cce9df6215b66e3d1b Mon Sep 17 00:00:00 2001 From: ismailarilik Date: Mon, 5 May 2025 16:36:04 +0300 Subject: [PATCH 148/262] Handle rustc_middle cases of rustc::potential_query_instability lint --- compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 2 +- .../rustc_middle/src/query/on_disk_cache.rs | 4 +-- compiler/rustc_middle/src/ty/context.rs | 7 ++--- compiler/rustc_middle/src/ty/diagnostics.rs | 4 +-- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 30 ++++++++----------- compiler/rustc_resolve/src/lib.rs | 2 +- .../clippy_lints/src/wildcard_imports.rs | 2 +- .../clippy/tests/ui/wildcard_imports.fixed | 10 +++---- .../clippy/tests/ui/wildcard_imports.stderr | 10 +++---- .../wildcard_imports_2021.edition2018.fixed | 10 +++---- .../wildcard_imports_2021.edition2018.stderr | 10 +++---- .../wildcard_imports_2021.edition2021.fixed | 10 +++---- .../wildcard_imports_2021.edition2021.stderr | 10 +++---- 15 files changed, 54 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1e6178144c92..9951b691be1b 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -27,7 +27,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0d5fba3cc69b..5f9f27b5fcd3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2169,7 +2169,7 @@ rustc_queries! { query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet { desc { "fetching potentially unused trait imports" } } - query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet { + query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxIndexSet { desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 14e3ce8bef6b..ce879be75fee 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use std::mem; use std::sync::Arc; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::sync::{HashMapExt, Lock, RwLock}; use rustc_data_structures::unhash::UnhashMap; @@ -57,7 +57,7 @@ pub struct OnDiskCache { // Collects all `QuerySideEffect` created during the current compilation // session. - current_side_effects: Lock>, + current_side_effects: Lock>, file_index_to_stable_id: FxHashMap, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 162ca1f4af85..87bd2785bedd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -28,7 +28,6 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; -use rustc_data_structures::unord::UnordSet; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, }; @@ -2378,6 +2377,8 @@ macro_rules! sty_debug_print { $(let mut $variant = total;)* for shard in tcx.interners.type_.lock_shards() { + // It seems that ordering doesn't affect anything here. + #[allow(rustc::potential_query_instability)] let types = shard.iter(); for &(InternedInSet(t), ()) in types { let variant = match t.internee { @@ -3355,9 +3356,7 @@ pub fn provide(providers: &mut Providers) { providers.maybe_unused_trait_imports = |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; providers.names_imported_by_glob_use = |tcx, id| { - tcx.arena.alloc(UnordSet::from( - tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(), - )) + tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default()) }; providers.extern_mod_stmt_cnum = diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index d3abb3d64b8c..e2bae831efc0 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use std::ops::ControlFlow; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{ Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, listify, pluralize, }; @@ -287,7 +287,7 @@ pub fn suggest_constraining_type_params<'a>( param_names_and_constraints: impl Iterator)>, span_to_replace: Option, ) -> bool { - let mut grouped = FxHashMap::default(); + let mut grouped = FxIndexMap::default(); let mut unstable_suggestion = false; param_names_and_constraints.for_each(|(param_name, constraint, def_id)| { let stable = match def_id { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 80f1bd7c6f46..d94331926ff4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -172,7 +172,7 @@ pub struct ResolverGlobalCtxt { pub extern_crate_map: UnordMap, pub maybe_unused_trait_imports: FxIndexSet, pub module_children: LocalDefIdMap>, - pub glob_map: FxHashMap>, + pub glob_map: FxIndexMap>, pub main_def: Option, pub trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3281cb4135a0..69940ab446c9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -6,7 +6,7 @@ use std::ops::{Deref, DerefMut}; use rustc_abi::{ExternAbi, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; use rustc_hir::LangItem; @@ -3489,8 +3489,8 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { // Once constructed, unique namespace+symbol pairs will have a `Some(_)` entry, while // non-unique pairs will have a `None` entry. - let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option> = - &mut FxHashMap::default(); + let unique_symbols_rev: &mut FxIndexMap<(Namespace, Symbol), Option> = + &mut FxIndexMap::default(); for symbol_set in tcx.resolutions(()).glob_map.values() { for symbol in symbol_set { @@ -3500,27 +3500,23 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { } } - for_each_def(tcx, |ident, ns, def_id| { - use std::collections::hash_map::Entry::{Occupied, Vacant}; - - match unique_symbols_rev.entry((ns, ident.name)) { - Occupied(mut v) => match v.get() { - None => {} - Some(existing) => { - if *existing != def_id { - v.insert(None); - } + for_each_def(tcx, |ident, ns, def_id| match unique_symbols_rev.entry((ns, ident.name)) { + IndexEntry::Occupied(mut v) => match v.get() { + None => {} + Some(existing) => { + if *existing != def_id { + v.insert(None); } - }, - Vacant(v) => { - v.insert(Some(def_id)); } + }, + IndexEntry::Vacant(v) => { + v.insert(Some(def_id)); } }); // Put the symbol from all the unique namespace+symbol pairs into `map`. let mut map: DefIdMap = Default::default(); - for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() { + for ((_, symbol), opt_def_id) in unique_symbols_rev.drain(..) { use std::collections::hash_map::Entry::{Occupied, Vacant}; if let Some(def_id) = opt_def_id { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3ac66840d87d..42f113959bd1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1104,7 +1104,7 @@ pub struct Resolver<'ra, 'tcx> { underscore_disambiguator: u32, /// Maps glob imports to the names of items actually imported. - glob_map: FxHashMap>, + glob_map: FxIndexMap>, glob_error: Option, visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>, used_imports: FxHashSet, diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs index 405310512dff..393060d52609 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs @@ -150,7 +150,7 @@ impl LateLintPass<'_> for WildcardImports { (span, false) }; - let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord(); + let mut imports: Vec<_> = used_imports.iter().map(ToString::to_string).collect(); let imports_string = if imports.len() == 1 { imports.pop().unwrap() } else if braced_glob { diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed index a26b4a34190c..17510683f03e 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed @@ -16,7 +16,7 @@ use crate::fn_mod::foo; //~^ wildcard_imports use crate::mod_mod::inner_mod; //~^ wildcard_imports -use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}; //~^ wildcard_imports #[macro_use] use crate::struct_mod::{A, inner_struct_mod}; @@ -26,7 +26,7 @@ use crate::struct_mod::{A, inner_struct_mod}; use wildcard_imports_helper::inner::inner_for_self_import; use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; //~^ wildcard_imports -use wildcard_imports_helper::{ExternA, extern_foo}; +use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports use std::io::prelude::*; @@ -138,7 +138,7 @@ mod in_fn_test { fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; //~^ wildcard_imports - use wildcard_imports_helper::{ExternA, extern_foo}; + use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); @@ -160,7 +160,7 @@ mod in_fn_test { } fn test_extern_reexported() { - use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}; //~^ wildcard_imports extern_exported(); @@ -190,7 +190,7 @@ mod in_fn_test { } fn test_reexported() { - use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}; //~^ wildcard_imports exported(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr index f774126102bc..26434656a509 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr @@ -17,7 +17,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports.rs:19:5 | LL | use crate::multi_fn_mod::*; - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}` error: usage of wildcard import --> tests/ui/wildcard_imports.rs:22:5 @@ -35,7 +35,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports.rs:29:5 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports.rs:100:13 @@ -59,7 +59,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports.rs:141:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports.rs:154:20 @@ -77,13 +77,13 @@ error: usage of wildcard import --> tests/ui/wildcard_imports.rs:163:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports.rs:193:9 | LL | use crate::in_fn_test::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports.rs:203:9 diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed index a3d1aebba8af..f97b883ea231 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed @@ -14,7 +14,7 @@ use crate::fn_mod::foo; //~^ wildcard_imports use crate::mod_mod::inner_mod; //~^ wildcard_imports -use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}; //~^ wildcard_imports use crate::struct_mod::{A, inner_struct_mod}; //~^ wildcard_imports @@ -23,7 +23,7 @@ use crate::struct_mod::{A, inner_struct_mod}; use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; //~^ wildcard_imports use wildcard_imports_helper::prelude::v1::*; -use wildcard_imports_helper::{ExternA, extern_foo}; +use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports use std::io::prelude::*; @@ -132,7 +132,7 @@ mod in_fn_test { fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; //~^ wildcard_imports - use wildcard_imports_helper::{ExternA, extern_foo}; + use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); @@ -154,7 +154,7 @@ mod in_fn_test { } fn test_extern_reexported() { - use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}; //~^ wildcard_imports extern_exported(); @@ -184,7 +184,7 @@ mod in_fn_test { } fn test_reexported() { - use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}; //~^ wildcard_imports exported(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr index a1b557f39f0d..873ce41b04f4 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr @@ -17,7 +17,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:17:5 | LL | use crate::multi_fn_mod::*; - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:19:5 @@ -35,7 +35,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:26:5 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:95:13 @@ -59,7 +59,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:135:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:148:20 @@ -77,13 +77,13 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:157:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:187:9 | LL | use crate::in_fn_test::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:197:9 diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed index a3d1aebba8af..f97b883ea231 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed @@ -14,7 +14,7 @@ use crate::fn_mod::foo; //~^ wildcard_imports use crate::mod_mod::inner_mod; //~^ wildcard_imports -use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}; //~^ wildcard_imports use crate::struct_mod::{A, inner_struct_mod}; //~^ wildcard_imports @@ -23,7 +23,7 @@ use crate::struct_mod::{A, inner_struct_mod}; use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; //~^ wildcard_imports use wildcard_imports_helper::prelude::v1::*; -use wildcard_imports_helper::{ExternA, extern_foo}; +use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports use std::io::prelude::*; @@ -132,7 +132,7 @@ mod in_fn_test { fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; //~^ wildcard_imports - use wildcard_imports_helper::{ExternA, extern_foo}; + use wildcard_imports_helper::{extern_foo, ExternA}; //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); @@ -154,7 +154,7 @@ mod in_fn_test { } fn test_extern_reexported() { - use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}; //~^ wildcard_imports extern_exported(); @@ -184,7 +184,7 @@ mod in_fn_test { } fn test_reexported() { - use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}; //~^ wildcard_imports exported(); diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr index a1b557f39f0d..873ce41b04f4 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr @@ -17,7 +17,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:17:5 | LL | use crate::multi_fn_mod::*; - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:19:5 @@ -35,7 +35,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:26:5 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:95:13 @@ -59,7 +59,7 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:135:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:148:20 @@ -77,13 +77,13 @@ error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:157:13 | LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:187:9 | LL | use crate::in_fn_test::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}` error: usage of wildcard import --> tests/ui/wildcard_imports_2021.rs:197:9 From 45598de7048f350f48651b67b4dfc4dfcb30deeb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 1 May 2025 18:52:41 +0000 Subject: [PATCH 149/262] Do not gather local all together at the beginning of typeck --- compiler/rustc_hir_typeck/src/_match.rs | 4 +- compiler/rustc_hir_typeck/src/check.rs | 5 +- compiler/rustc_hir_typeck/src/expr.rs | 10 +-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +- .../rustc_hir_typeck/src/gather_locals.rs | 51 +++++++++++--- compiler/rustc_hir_typeck/src/lib.rs | 4 -- .../async-closures/def-path.stderr | 4 +- ...re-print-generic-trim-off-verbose-2.stderr | 2 +- .../closure-print-generic-verbose-2.stderr | 2 +- .../const-arg-in-const-arg.min.stderr | 70 +++++++++---------- .../dependence_lint.gce.stderr | 38 +++++----- tests/ui/const-generics/invalid-enum.stderr | 44 ++++++------ ...tion-correct-dyn-incompatible-trait.stderr | 36 +++++----- tests/ui/issues/issue-18959.rs | 1 - tests/ui/issues/issue-18959.stderr | 24 ++----- tests/ui/lint/bare-trait-objects-path.stderr | 40 +++++------ .../disambiguate-multiple-blanket-impl.stderr | 30 ++++---- .../methods/disambiguate-multiple-impl.stderr | 30 ++++---- .../disambiguate-multiple-trait-2.stderr | 64 ++++++++--------- .../disambiguate-multiple-trait.stderr | 30 ++++---- .../generics-default-stability.stderr | 48 ++++++------- .../suggest-vec-allocator-api.stderr | 20 +++--- .../bound/on-structs-and-enums-locals.stderr | 34 ++++----- .../bound/on-structs-and-enums-xc1.stderr | 24 +++---- 24 files changed, 318 insertions(+), 303 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 38319862334a..2e7831f16aee 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -11,7 +11,7 @@ use rustc_trait_selection::traits::{ use tracing::{debug, instrument}; use crate::coercion::{AsCoercionSite, CoerceMany}; -use crate::{Diverges, Expectation, FnCtxt, Needs}; +use crate::{Diverges, Expectation, FnCtxt, GatherLocalsVisitor, Needs}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug", ret)] @@ -43,6 +43,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // #55810: Type check patterns first so we get types for all bindings. let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span); for arm in arms { + GatherLocalsVisitor::gather_from_arm(self, arm); + self.check_pat_top(arm.pat, scrutinee_ty, Some(scrut_span), Some(scrut), None); } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 2189fdf0f343..99103f14d682 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -3,7 +3,6 @@ use std::cell::RefCell; use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::check::check_function_signature; use rustc_infer::infer::RegionVariableOrigin; @@ -50,7 +49,9 @@ pub(super) fn check_fn<'a, 'tcx>( let span = body.value.span; - GatherLocalsVisitor::new(fcx).visit_body(body); + for param in body.params { + GatherLocalsVisitor::gather_from_param(fcx, param); + } // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index db2650ed357e..2c28ffd1fe3d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -16,7 +16,6 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::NoVariantNamed; @@ -50,8 +49,8 @@ use crate::errors::{ YieldExprOutsideOfCoroutine, }; use crate::{ - BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, TupleArgumentsFlag, cast, - fatally_break_rust, report_unexpected_variant_res, type_error_struct, + BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, GatherLocalsVisitor, Needs, + TupleArgumentsFlag, cast, fatally_break_rust, report_unexpected_variant_res, type_error_struct, }; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -1518,11 +1517,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let_expr: &'tcx hir::LetExpr<'tcx>, hir_id: HirId, ) -> Ty<'tcx> { + GatherLocalsVisitor::gather_from_let_expr(self, let_expr, hir_id); + // for let statements, this is done in check_stmt let init = let_expr.init; self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression"); + // otherwise check exactly as a let statement self.check_decl((let_expr, hir_id).into()); + // but return a bool, for this is a boolean expression if let ast::Recovered::Yes(error_guaranteed) = let_expr.recovered { self.set_tainted_by_errors(error_guaranteed); @@ -1827,7 +1830,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a new function context. let def_id = block.def_id; let fcx = FnCtxt::new(self, self.param_env, def_id); - crate::GatherLocalsVisitor::new(&fcx).visit_body(body); let ty = fcx.check_expr_with_expectation(body.value, expected); fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::SizedConstOrStatic); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c804dc5e7fba..6cc7e82bbf73 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -37,8 +37,8 @@ use crate::method::probe::IsSuggestion; use crate::method::probe::Mode::MethodCall; use crate::method::probe::ProbeScope::TraitsInScope; use crate::{ - BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, Needs, TupleArgumentsFlag, errors, - struct_span_code_err, + BreakableCtxt, Diverges, Expectation, FnCtxt, GatherLocalsVisitor, LoweredTy, Needs, + TupleArgumentsFlag, errors, struct_span_code_err, }; rustc_index::newtype_index! { @@ -1765,6 +1765,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Type check a `let` statement. fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) { + GatherLocalsVisitor::gather_from_local(self, local); + let ty = self.check_decl(local.into()); self.write_ty(local.hir_id, ty); if local.pat.is_never_pattern() { diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 5d87e800096f..a8bbc89dbded 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -55,6 +55,14 @@ impl<'a> From<(&'a hir::LetExpr<'a>, HirId)> for Declaration<'a> { } } +/// The `GatherLocalsVisitor` is responsible for initializing local variable types +/// in the [`ty::TypeckResults`] for all subpatterns in statements and expressions +/// like `let`, `match`, and params of function bodies. It also adds `Sized` bounds +/// for these types (with exceptions for unsized feature gates like `unsized_fn_params`). +/// +/// Failure to visit locals will cause an ICE in writeback when the local's type is +/// resolved. Visiting locals twice will ICE in the `GatherLocalsVisitor`, since it +/// will overwrite the type previously stored in the local. pub(super) struct GatherLocalsVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, // parameters are special cases of patterns, but we want to handle them as @@ -63,9 +71,37 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> { outermost_fn_param_pat: Option<(Span, HirId)>, } +// N.B. additional `gather_*` functions should be careful to only walk the pattern +// for new expressions, since visiting sub-expressions or nested bodies may initialize +// locals which are not conceptually owned by the gathered statement or expression. impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { - pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self { - Self { fcx, outermost_fn_param_pat: None } + pub(crate) fn gather_from_local(fcx: &'a FnCtxt<'a, 'tcx>, local: &'tcx hir::LetStmt<'tcx>) { + let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None }; + visitor.declare(local.into()); + visitor.visit_pat(local.pat); + } + + pub(crate) fn gather_from_let_expr( + fcx: &'a FnCtxt<'a, 'tcx>, + let_expr: &'tcx hir::LetExpr<'tcx>, + expr_hir_id: hir::HirId, + ) { + let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None }; + visitor.declare((let_expr, expr_hir_id).into()); + visitor.visit_pat(let_expr.pat); + } + + pub(crate) fn gather_from_param(fcx: &'a FnCtxt<'a, 'tcx>, param: &'tcx hir::Param<'tcx>) { + let mut visitor = GatherLocalsVisitor { + fcx, + outermost_fn_param_pat: Some((param.ty_span, param.hir_id)), + }; + visitor.visit_pat(param.pat); + } + + pub(crate) fn gather_from_arm(fcx: &'a FnCtxt<'a, 'tcx>, local: &'tcx hir::Arm<'tcx>) { + let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None }; + visitor.visit_pat(local.pat); } fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option>) -> Ty<'tcx> { @@ -73,12 +109,12 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { None => { // Infer the variable's type. let var_ty = self.fcx.next_ty_var(span); - self.fcx.locals.borrow_mut().insert(nid, var_ty); + assert_eq!(self.fcx.locals.borrow_mut().insert(nid, var_ty), None); var_ty } Some(typ) => { // Take type that the user specified. - self.fcx.locals.borrow_mut().insert(nid, typ); + assert_eq!(self.fcx.locals.borrow_mut().insert(nid, typ), None); typ } } @@ -133,13 +169,6 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { intravisit::walk_expr(self, expr) } - fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { - let old_outermost_fn_param_pat = - self.outermost_fn_param_pat.replace((param.ty_span, param.hir_id)); - intravisit::walk_param(self, param); - self.outermost_fn_param_pat = old_outermost_fn_param_pat; - } - // Add pattern bindings. fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { if let PatKind::Binding(_, _, ident, _) = p.kind { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d861a4f81b0e..78233a34c461 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -46,7 +46,6 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, HirIdMap, Node}; use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; @@ -191,9 +190,6 @@ fn typeck_with_inspect<'tcx>( let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code); - // Gather locals in statics (because of block expressions). - GatherLocalsVisitor::new(&fcx).visit_body(body); - fcx.check_expr_coercible_to_type(body.value, expected_type, None); fcx.write_ty(id, expected_type); diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index 13ebaf67e54a..b50e353b6988 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -5,11 +5,11 @@ LL | let x = async || {}; | -- the expected `async` closure body LL | LL | let () = x(); - | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?6t}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?6t}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}` found unit type `()` error: aborting due to 1 previous error diff --git a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr index b71cfc503339..bcf5759a194f 100644 --- a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr +++ b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr @@ -9,7 +9,7 @@ LL | let c1 : () = c; | expected due to this | = note: expected unit type `()` - found closure `{mod1::f::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}` + found closure `{mod1::f::{closure#0} closure_kind_ty=?7t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?6t}` help: use parentheses to call this closure | LL | let c1 : () = c(); diff --git a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr index 88f4dc9b92ab..a8d2b07a00dc 100644 --- a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr +++ b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr @@ -9,7 +9,7 @@ LL | let c1 : () = c; | expected due to this | = note: expected unit type `()` - found closure `{f::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}` + found closure `{f::{closure#0} closure_kind_ty=?7t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?6t}` help: use parentheses to call this closure | LL | let c1 : () = c(); diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index 06a6a5f59d6d..16512cb69e23 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -240,41 +240,6 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:36:24 - | -LL | let _: Foo<{ bar::() }>; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Foo<{ bar::<{ N }>() }>; - | + + - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:38:24 - | -LL | let _: Foo<{ faz::<'a>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:10:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:41:24 - | -LL | let _: Foo<{ faz::<'b>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:10:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - error: constant expression depends on a generic parameter --> $DIR/const-arg-in-const-arg.rs:25:17 | @@ -326,6 +291,41 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:36:24 + | +LL | let _: Foo<{ bar::() }>; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: Foo<{ bar::<{ N }>() }>; + | + + + +error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:38:24 + | +LL | let _: Foo<{ faz::<'a>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:10:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:41:24 + | +LL | let _: Foo<{ faz::<'b>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:10:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + error[E0747]: unresolved item provided when a constant was expected --> $DIR/const-arg-in-const-arg.rs:45:27 | diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr index 7e318f8786f3..f6119c17bf47 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr @@ -1,22 +1,3 @@ -error: overly complex generic constant - --> $DIR/dependence_lint.rs:21:17 - | -LL | let _: [u8; if true { size_of::() } else { 3 }]; // error on stable, error with gce - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants - | - = help: consider moving this anonymous constant into a `const` function - -error: unconstrained generic constant - --> $DIR/dependence_lint.rs:14:12 - | -LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound - | -LL | fn foo() where [(); size_of::<*mut T>()]: { - | ++++++++++++++++++++++++++++++++ - error: unconstrained generic constant --> $DIR/dependence_lint.rs:10:9 | @@ -36,5 +17,24 @@ LL | [0; if false { size_of::() } else { 3 }]; // lint on stable, error w | = help: consider moving this anonymous constant into a `const` function +error: unconstrained generic constant + --> $DIR/dependence_lint.rs:14:12 + | +LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try adding a `where` bound + | +LL | fn foo() where [(); size_of::<*mut T>()]: { + | ++++++++++++++++++++++++++++++++ + +error: overly complex generic constant + --> $DIR/dependence_lint.rs:21:17 + | +LL | let _: [u8; if true { size_of::() } else { 3 }]; // error on stable, error with gce + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants + | + = help: consider moving this anonymous constant into a `const` function + error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr index 7e8a632b34f7..f588ff0bc8eb 100644 --- a/tests/ui/const-generics/invalid-enum.stderr +++ b/tests/ui/const-generics/invalid-enum.stderr @@ -25,28 +25,6 @@ LL | let _: Example = Example { x: 0 }; | not a type | help: try using the variant's enum: `CompileFlag` -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:31:18 - | -LL | let _: Example = Example { x: 0 }; - | ^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 }; - | + + - -error[E0747]: type provided when a constant was expected - --> $DIR/invalid-enum.rs:35:18 - | -LL | let _: Example = Example { x: 0 }; - | ^^^^^^^^^^^^^^^^^^^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 }; - | + + - error[E0747]: unresolved item provided when a constant was expected --> $DIR/invalid-enum.rs:23:12 | @@ -69,6 +47,28 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | test_2::<_, { CompileFlag::A }>(0); | + + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/invalid-enum.rs:31:18 + | +LL | let _: Example = Example { x: 0 }; + | ^^^^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 }; + | + + + +error[E0747]: type provided when a constant was expected + --> $DIR/invalid-enum.rs:35:18 + | +LL | let _: Example = Example { x: 0 }; + | ^^^^^^^^^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 }; + | + + + error: aborting due to 7 previous errors Some errors have detailed explanations: E0573, E0747. diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr index bb3f7899bf1c..c1e93ccb83ca 100644 --- a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr +++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr @@ -1,21 +1,3 @@ -error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15 - | -LL | let test: &mut dyn Bar = &mut thing; - | ^^^^^^^^^^^^ `Bar` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8 - | -LL | fn foo(&self, val: T); - | ^^^ ...because method `foo` has generic type parameters -... -LL | trait Bar: Foo { } - | --- this trait is not dyn compatible... - = help: consider moving `foo` to another trait - = help: only type `Thing` implements `Bar`; consider using it directly instead. - error[E0038]: the trait `Bar` is not dyn compatible --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:30 | @@ -35,6 +17,24 @@ LL | trait Bar: Foo { } = help: only type `Thing` implements `Bar`; consider using it directly instead. = note: required for the cast from `&mut Thing` to `&mut dyn Bar` +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15 + | +LL | let test: &mut dyn Bar = &mut thing; + | ^^^^^^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8 + | +LL | fn foo(&self, val: T); + | ^^^ ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait is not dyn compatible... + = help: consider moving `foo` to another trait + = help: only type `Thing` implements `Bar`; consider using it directly instead. + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/issues/issue-18959.rs b/tests/ui/issues/issue-18959.rs index f4cab630f2e9..6aeb34879ea1 100644 --- a/tests/ui/issues/issue-18959.rs +++ b/tests/ui/issues/issue-18959.rs @@ -20,5 +20,4 @@ fn main() { //~^ ERROR E0038 //~| ERROR E0038 foo(test); - //~^ ERROR E0038 } diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr index c37c4177bfc1..1e050b115e57 100644 --- a/tests/ui/issues/issue-18959.stderr +++ b/tests/ui/issues/issue-18959.stderr @@ -30,22 +30,6 @@ LL | pub trait Bar: Foo { } | --- this trait is not dyn compatible... = help: consider moving `foo` to another trait -error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-18959.rs:19:15 - | -LL | let test: &dyn Bar = &mut thing; - | ^^^^^^^^ `Bar` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-18959.rs:1:20 - | -LL | pub trait Foo { fn foo(&self, ext_thing: &T); } - | ^^^ ...because method `foo` has generic type parameters -LL | pub trait Bar: Foo { } - | --- this trait is not dyn compatible... - = help: consider moving `foo` to another trait - error[E0038]: the trait `Bar` is not dyn compatible --> $DIR/issue-18959.rs:19:26 | @@ -64,10 +48,10 @@ LL | pub trait Bar: Foo { } = note: required for the cast from `&mut Thing` to `&dyn Bar` error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-18959.rs:22:9 + --> $DIR/issue-18959.rs:19:15 | -LL | foo(test); - | ^^^^ `Bar` is not dyn compatible +LL | let test: &dyn Bar = &mut thing; + | ^^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit @@ -79,6 +63,6 @@ LL | pub trait Bar: Foo { } | --- this trait is not dyn compatible... = help: consider moving `foo` to another trait -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr index d2d139dd025a..fbb647c37c5a 100644 --- a/tests/ui/lint/bare-trait-objects-path.stderr +++ b/tests/ui/lint/bare-trait-objects-path.stderr @@ -1,23 +1,3 @@ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/bare-trait-objects-path.rs:23:12 - | -LL | let _: Dyn::Ty; - | ^^^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - = note: `#[warn(bare_trait_objects)]` on by default -help: if this is a dyn-compatible trait, use `dyn` - | -LL | let _: ::Ty; - | ++++ + - -error[E0223]: ambiguous associated type - --> $DIR/bare-trait-objects-path.rs:23:12 - | -LL | let _: Dyn::Ty; - | ^^^^^^^ help: use fully-qualified syntax: `::Ty` - warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:14:5 | @@ -26,6 +6,7 @@ LL | Dyn::func(); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: `#[warn(bare_trait_objects)]` on by default help: if this is a dyn-compatible trait, use `dyn` | LL | ::func(); @@ -57,6 +38,25 @@ help: if this is a dyn-compatible trait, use `dyn` LL | ::CONST; | ++++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/bare-trait-objects-path.rs:23:12 + | +LL | let _: Dyn::Ty; + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is a dyn-compatible trait, use `dyn` + | +LL | let _: ::Ty; + | ++++ + + +error[E0223]: ambiguous associated type + --> $DIR/bare-trait-objects-path.rs:23:12 + | +LL | let _: Dyn::Ty; + | ^^^^^^^ help: use fully-qualified syntax: `::Ty` + error: aborting due to 1 previous error; 4 warnings emitted For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr index 1b81dc5aafb7..ee698ed0e75f 100644 --- a/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr +++ b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr @@ -1,18 +1,3 @@ -error[E0223]: ambiguous associated type - --> $DIR/disambiguate-multiple-blanket-impl.rs:36:12 - | -LL | let _: S::Type; - | ^^^^^^^ - | -help: use fully-qualified syntax - | -LL - let _: S::Type; -LL + let _: ::Type; - | -LL - let _: S::Type; -LL + let _: ::Type; - | - error[E0034]: multiple applicable items in scope --> $DIR/disambiguate-multiple-blanket-impl.rs:30:8 | @@ -63,6 +48,21 @@ LL - S::CONST; LL + ::CONST; | +error[E0223]: ambiguous associated type + --> $DIR/disambiguate-multiple-blanket-impl.rs:36:12 + | +LL | let _: S::Type; + | ^^^^^^^ + | +help: use fully-qualified syntax + | +LL - let _: S::Type; +LL + let _: ::Type; + | +LL - let _: S::Type; +LL + let _: ::Type; + | + error: aborting due to 3 previous errors Some errors have detailed explanations: E0034, E0223. diff --git a/tests/ui/methods/disambiguate-multiple-impl.stderr b/tests/ui/methods/disambiguate-multiple-impl.stderr index 2563c2327b7a..319d5886f8ed 100644 --- a/tests/ui/methods/disambiguate-multiple-impl.stderr +++ b/tests/ui/methods/disambiguate-multiple-impl.stderr @@ -1,18 +1,3 @@ -error[E0223]: ambiguous associated type - --> $DIR/disambiguate-multiple-impl.rs:32:12 - | -LL | let _: S::Type = (); - | ^^^^^^^ - | -help: use fully-qualified syntax - | -LL - let _: S::Type = (); -LL + let _: ::Type = (); - | -LL - let _: S::Type = (); -LL + let _: ::Type = (); - | - error[E0034]: multiple applicable items in scope --> $DIR/disambiguate-multiple-impl.rs:29:8 | @@ -38,6 +23,21 @@ LL - S::foo(&s); LL + B::foo(&s); | +error[E0223]: ambiguous associated type + --> $DIR/disambiguate-multiple-impl.rs:32:12 + | +LL | let _: S::Type = (); + | ^^^^^^^ + | +help: use fully-qualified syntax + | +LL - let _: S::Type = (); +LL + let _: ::Type = (); + | +LL - let _: S::Type = (); +LL + let _: ::Type = (); + | + error[E0034]: multiple applicable items in scope --> $DIR/disambiguate-multiple-impl.rs:34:16 | diff --git a/tests/ui/methods/disambiguate-multiple-trait-2.stderr b/tests/ui/methods/disambiguate-multiple-trait-2.stderr index 08e264c20c89..f9119e607501 100644 --- a/tests/ui/methods/disambiguate-multiple-trait-2.stderr +++ b/tests/ui/methods/disambiguate-multiple-trait-2.stderr @@ -1,26 +1,3 @@ -error[E0221]: ambiguous associated type `Type` in bounds of `T` - --> $DIR/disambiguate-multiple-trait-2.rs:23:12 - | -LL | type Type; - | --------- ambiguous `Type` from `A` -... -LL | type Type; - | --------- ambiguous `Type` from `B` -... -LL | let _: T::Type; - | ^^^^^^^ ambiguous associated type `Type` - | -help: use fully-qualified syntax to disambiguate - | -LL - let _: T::Type; -LL + let _: ::Type; - | -help: use fully-qualified syntax to disambiguate - | -LL - let _: T::Type; -LL + let _: ::Type; - | - error[E0034]: multiple applicable items in scope --> $DIR/disambiguate-multiple-trait-2.rs:16:7 | @@ -73,19 +50,27 @@ LL - let _ = T::CONST; LL + let _ = ::CONST; | -error[E0223]: ambiguous associated type - --> $DIR/disambiguate-multiple-trait-2.rs:52:12 +error[E0221]: ambiguous associated type `Type` in bounds of `T` + --> $DIR/disambiguate-multiple-trait-2.rs:23:12 | -LL | let _: S::Type; - | ^^^^^^^ +LL | type Type; + | --------- ambiguous `Type` from `A` +... +LL | type Type; + | --------- ambiguous `Type` from `B` +... +LL | let _: T::Type; + | ^^^^^^^ ambiguous associated type `Type` | -help: use fully-qualified syntax +help: use fully-qualified syntax to disambiguate | -LL - let _: S::Type; -LL + let _: ::Type; +LL - let _: T::Type; +LL + let _: ::Type; | -LL - let _: S::Type; -LL + let _: ::Type; +help: use fully-qualified syntax to disambiguate + | +LL - let _: T::Type; +LL + let _: ::Type; | error[E0034]: multiple applicable items in scope @@ -138,6 +123,21 @@ LL - let _ = S::CONST; LL + let _ = ::CONST; | +error[E0223]: ambiguous associated type + --> $DIR/disambiguate-multiple-trait-2.rs:52:12 + | +LL | let _: S::Type; + | ^^^^^^^ + | +help: use fully-qualified syntax + | +LL - let _: S::Type; +LL + let _: ::Type; + | +LL - let _: S::Type; +LL + let _: ::Type; + | + error: aborting due to 6 previous errors Some errors have detailed explanations: E0034, E0221, E0223. diff --git a/tests/ui/methods/disambiguate-multiple-trait.stderr b/tests/ui/methods/disambiguate-multiple-trait.stderr index a977fe2cd033..f35eec3b048c 100644 --- a/tests/ui/methods/disambiguate-multiple-trait.stderr +++ b/tests/ui/methods/disambiguate-multiple-trait.stderr @@ -1,18 +1,3 @@ -error[E0223]: ambiguous associated type - --> $DIR/disambiguate-multiple-trait.rs:30:12 - | -LL | let _: S::Type; - | ^^^^^^^ - | -help: use fully-qualified syntax - | -LL - let _: S::Type; -LL + let _: ::Type; - | -LL - let _: S::Type; -LL + let _: ::Type; - | - error[E0034]: multiple applicable items in scope --> $DIR/disambiguate-multiple-trait.rs:24:8 | @@ -63,6 +48,21 @@ LL - let _ = S::CONST; LL + let _ = ::CONST; | +error[E0223]: ambiguous associated type + --> $DIR/disambiguate-multiple-trait.rs:30:12 + | +LL | let _: S::Type; + | ^^^^^^^ + | +help: use fully-qualified syntax + | +LL - let _: S::Type; +LL + let _: ::Type; + | +LL - let _: S::Type; +LL + let _: ::Type; + | + error: aborting due to 3 previous errors Some errors have detailed explanations: E0034, E0223. diff --git a/tests/ui/stability-attribute/generics-default-stability.stderr b/tests/ui/stability-attribute/generics-default-stability.stderr index f4f51a14248e..53ef3e170cc1 100644 --- a/tests/ui/stability-attribute/generics-default-stability.stderr +++ b/tests/ui/stability-attribute/generics-default-stability.stderr @@ -270,6 +270,18 @@ LL | let _: Struct3 = Struct3 { field1: 0, field2: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +warning: use of deprecated field `unstable_generic_param::Struct4::field`: test + --> $DIR/generics-default-stability.rs:71:39 + | +LL | let _: Struct4 = Struct4 { field: 1 }; + | ^^^^^^^^ + +warning: use of deprecated field `unstable_generic_param::Struct4::field`: test + --> $DIR/generics-default-stability.rs:78:39 + | +LL | let _: Struct4 = Struct4 { field: 0 }; + | ^^^^^^^^ + error[E0658]: use of unstable library feature `unstable_default` --> $DIR/generics-default-stability.rs:84:20 | @@ -279,6 +291,12 @@ LL | let _: Struct5 = Struct5 { field: 1 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +warning: use of deprecated field `unstable_generic_param::Struct5::field`: test + --> $DIR/generics-default-stability.rs:84:39 + | +LL | let _: Struct5 = Struct5 { field: 1 }; + | ^^^^^^^^ + error[E0658]: use of unstable library feature `unstable_default` --> $DIR/generics-default-stability.rs:90:20 | @@ -297,6 +315,12 @@ LL | let _: Struct5 = Struct5 { field: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +warning: use of deprecated field `unstable_generic_param::Struct5::field`: test + --> $DIR/generics-default-stability.rs:92:39 + | +LL | let _: Struct5 = Struct5 { field: 0 }; + | ^^^^^^^^ + error[E0658]: use of unstable library feature `unstable_default` --> $DIR/generics-default-stability.rs:100:19 | @@ -468,30 +492,6 @@ LL | let _: Box1 = Box1::new(1); = help: add `#![feature(box_alloc_param)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: use of deprecated field `unstable_generic_param::Struct4::field`: test - --> $DIR/generics-default-stability.rs:71:39 - | -LL | let _: Struct4 = Struct4 { field: 1 }; - | ^^^^^^^^ - -warning: use of deprecated field `unstable_generic_param::Struct4::field`: test - --> $DIR/generics-default-stability.rs:78:39 - | -LL | let _: Struct4 = Struct4 { field: 0 }; - | ^^^^^^^^ - -warning: use of deprecated field `unstable_generic_param::Struct5::field`: test - --> $DIR/generics-default-stability.rs:84:39 - | -LL | let _: Struct5 = Struct5 { field: 1 }; - | ^^^^^^^^ - -warning: use of deprecated field `unstable_generic_param::Struct5::field`: test - --> $DIR/generics-default-stability.rs:92:39 - | -LL | let _: Struct5 = Struct5 { field: 0 }; - | ^^^^^^^^ - error: aborting due to 28 previous errors; 40 warnings emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr b/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr index 6662ceda90b9..78b7d07b60cc 100644 --- a/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr +++ b/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr @@ -26,16 +26,6 @@ LL + String, LL ~ _)> = vec![]; | -error[E0658]: use of unstable library feature `allocator_api` - --> $DIR/suggest-vec-allocator-api.rs:8:26 - | -LL | let _boxed: Box = Box::new(10); - | ^ - | - = note: see issue #32838 for more information - = help: add `#![feature(allocator_api)]` 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]: use of unstable library feature `allocator_api` --> $DIR/suggest-vec-allocator-api.rs:7:24 | @@ -48,6 +38,16 @@ LL | let _ = Vec::::new(); = help: add `#![feature(allocator_api)]` 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]: use of unstable library feature `allocator_api` + --> $DIR/suggest-vec-allocator-api.rs:8:26 + | +LL | let _boxed: Box = Box::new(10); + | ^ + | + = note: see issue #32838 for more information + = help: add `#![feature(allocator_api)]` 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 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr index 01cf76c62d54..88077f4e4d7d 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -1,20 +1,3 @@ -error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-locals.rs:15:14 - | -LL | let baz: Foo = loop { }; - | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` - | -help: this trait has no implementations, consider adding one - --> $DIR/on-structs-and-enums-locals.rs:1:1 - | -LL | trait Trait { - | ^^^^^^^^^^^ -note: required by a bound in `Foo` - --> $DIR/on-structs-and-enums-locals.rs:5:14 - | -LL | struct Foo { - | ^^^^^ required by this bound in `Foo` - error[E0277]: the trait bound `{integer}: Trait` is not satisfied --> $DIR/on-structs-and-enums-locals.rs:11:12 | @@ -32,6 +15,23 @@ note: required by a bound in `Foo` LL | struct Foo { | ^^^^^ required by this bound in `Foo` +error[E0277]: the trait bound `usize: Trait` is not satisfied + --> $DIR/on-structs-and-enums-locals.rs:15:14 + | +LL | let baz: Foo = loop { }; + | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` + | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-locals.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ +note: required by a bound in `Foo` + --> $DIR/on-structs-and-enums-locals.rs:5:14 + | +LL | struct Foo { + | ^^^^^ required by this bound in `Foo` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr index 3fb5decb723e..1f46415e2436 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -1,15 +1,3 @@ -error[E0277]: the trait bound `f64: Trait` is not satisfied - --> $DIR/on-structs-and-enums-xc1.rs:12:14 - | -LL | let bar: Bar = return; - | ^^^^^^^^ the trait `Trait` is not implemented for `f64` - | -note: required by a bound in `Bar` - --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 - | -LL | pub enum Bar { - | ^^^^^ required by this bound in `Bar` - error[E0277]: the trait bound `{integer}: Trait` is not satisfied --> $DIR/on-structs-and-enums-xc1.rs:9:12 | @@ -22,6 +10,18 @@ note: required by a bound in `Foo` LL | pub struct Foo { | ^^^^^ required by this bound in `Foo` +error[E0277]: the trait bound `f64: Trait` is not satisfied + --> $DIR/on-structs-and-enums-xc1.rs:12:14 + | +LL | let bar: Bar = return; + | ^^^^^^^^ the trait `Trait` is not implemented for `f64` + | +note: required by a bound in `Bar` + --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 + | +LL | pub enum Bar { + | ^^^^^ required by this bound in `Bar` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. From 896cf8029c6a87b920e05dd569482dad6adbddfc Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 5 May 2025 22:56:03 +0800 Subject: [PATCH 150/262] Add ui test fn-trait-use-named-params Signed-off-by: xizheyin --- .../fn-trait-use-named-params-issue-140169.rs | 6 ++++++ ...trait-use-named-params-issue-140169.stderr | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/ui/fn/fn-trait-use-named-params-issue-140169.rs create mode 100644 tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs new file mode 100644 index 000000000000..fae5f6c15193 --- /dev/null +++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs @@ -0,0 +1,6 @@ +fn g(_: fn(a: u8)) {} +fn x(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` +fn y(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` +fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` + +fn main(){} diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr new file mode 100644 index 000000000000..e599afb1345f --- /dev/null +++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr @@ -0,0 +1,20 @@ +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` + --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:25 + | +LL | fn x(_: impl Fn(u8, vvvv: u8)) {} + | ^ expected one of 7 possible tokens + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` + --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:21 + | +LL | fn y(_: impl Fn(aaaa: u8, u8)) {} + | ^ expected one of 7 possible tokens + +error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` + --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:21 + | +LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} + | ^ expected one of 7 possible tokens + +error: aborting due to 3 previous errors + From 29f9aaf5038ba61d9a8ef8d1deb642d389c82ba0 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 5 May 2025 14:56:56 +0000 Subject: [PATCH 151/262] calculate step duration in a panic-safe way Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index c32d9c2870cf..6469bb5f2722 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1534,7 +1534,7 @@ impl<'a> Builder<'a> { let out = step.clone().run(self); let dur = start.elapsed(); let deps = self.time_spent_on_dependencies.replace(parent + dur); - (out, dur - deps) + (out, dur.saturating_sub(deps)) }; if self.config.print_step_timings && !self.config.dry_run() { From 662182637e100642d1e5de7cb193da837a14ae48 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 12 Apr 2025 15:53:46 +0000 Subject: [PATCH 152/262] Implement RFC 3503: frontmatters Supercedes #137193 --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_lexer/src/cursor.rs | 14 +- compiler/rustc_lexer/src/lib.rs | 155 +++++++++++++++++- compiler/rustc_lexer/src/tests.rs | 2 +- compiler/rustc_parse/messages.ftl | 13 ++ compiler/rustc_parse/src/errors.rs | 55 +++++++ compiler/rustc_parse/src/lexer/mod.rs | 106 +++++++++++- compiler/rustc_span/src/symbol.rs | 1 + .../language-features/arbitrary-self-types.md | 2 +- .../src/language-features/f128.md | 2 +- .../src/language-features/f16.md | 2 +- .../src/language-features/frontmatter.md | 25 +++ src/librustdoc/html/highlight.rs | 6 +- .../crates/parser/src/lexed_str.rs | 9 + .../parser/src/syntax_kind/generated.rs | 4 +- .../rust-analyzer/crates/syntax/rust.ungram | 1 + .../crates/syntax/src/ast/generated/nodes.rs | 4 + .../xtask/src/codegen/grammar.rs | 1 + .../feature-gates/feature-gate-frontmatter.rs | 5 + .../feature-gate-frontmatter.stderr | 15 ++ tests/ui/frontmatter/auxiliary/lib.rs | 6 + tests/ui/frontmatter/auxiliary/makro.rs | 8 + .../frontmatter/dot-in-infostring-leading.rs | 9 + .../dot-in-infostring-leading.stderr | 10 ++ .../dot-in-infostring-non-leading.rs | 9 + tests/ui/frontmatter/escape.rs | 14 ++ tests/ui/frontmatter/extra-after-end.rs | 7 + tests/ui/frontmatter/extra-after-end.stderr | 8 + .../frontmatter/frontmatter-after-tokens.rs | 10 ++ .../frontmatter-after-tokens.stderr | 10 ++ .../frontmatter-non-lexible-tokens.rs | 12 ++ .../frontmatter/frontmatter-whitespace-1.rs | 10 ++ .../frontmatter-whitespace-1.stderr | 26 +++ .../frontmatter/frontmatter-whitespace-2.rs | 15 ++ .../frontmatter-whitespace-2.stderr | 26 +++ .../frontmatter/frontmatter-whitespace-3.rs | 16 ++ .../frontmatter/frontmatter-whitespace-4.rs | 9 + tests/ui/frontmatter/included-frontmatter.rs | 12 ++ tests/ui/frontmatter/infostring-fail.rs | 9 + tests/ui/frontmatter/infostring-fail.stderr | 10 ++ tests/ui/frontmatter/mismatch-1.rs | 10 ++ tests/ui/frontmatter/mismatch-1.stderr | 16 ++ tests/ui/frontmatter/mismatch-2.rs | 8 + tests/ui/frontmatter/mismatch-2.stderr | 22 +++ tests/ui/frontmatter/multifrontmatter-2.rs | 12 ++ .../ui/frontmatter/multifrontmatter-2.stderr | 22 +++ tests/ui/frontmatter/multifrontmatter.rs | 13 ++ tests/ui/frontmatter/multifrontmatter.stderr | 10 ++ tests/ui/frontmatter/proc-macro-observer.rs | 12 ++ tests/ui/frontmatter/shebang.rs | 13 ++ tests/ui/frontmatter/unclosed-1.rs | 10 ++ tests/ui/frontmatter/unclosed-1.stderr | 16 ++ tests/ui/frontmatter/unclosed-2.rs | 15 ++ tests/ui/frontmatter/unclosed-2.stderr | 31 ++++ tests/ui/frontmatter/unclosed-3.rs | 16 ++ tests/ui/frontmatter/unclosed-3.stderr | 41 +++++ tests/ui/frontmatter/unclosed-4.rs | 9 + tests/ui/frontmatter/unclosed-4.stderr | 16 ++ tests/ui/frontmatter/unclosed-5.rs | 10 ++ tests/ui/frontmatter/unclosed-5.stderr | 29 ++++ 61 files changed, 970 insertions(+), 22 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/frontmatter.md create mode 100644 tests/ui/feature-gates/feature-gate-frontmatter.rs create mode 100644 tests/ui/feature-gates/feature-gate-frontmatter.stderr create mode 100644 tests/ui/frontmatter/auxiliary/lib.rs create mode 100644 tests/ui/frontmatter/auxiliary/makro.rs create mode 100644 tests/ui/frontmatter/dot-in-infostring-leading.rs create mode 100644 tests/ui/frontmatter/dot-in-infostring-leading.stderr create mode 100644 tests/ui/frontmatter/dot-in-infostring-non-leading.rs create mode 100644 tests/ui/frontmatter/escape.rs create mode 100644 tests/ui/frontmatter/extra-after-end.rs create mode 100644 tests/ui/frontmatter/extra-after-end.stderr create mode 100644 tests/ui/frontmatter/frontmatter-after-tokens.rs create mode 100644 tests/ui/frontmatter/frontmatter-after-tokens.stderr create mode 100644 tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-1.rs create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-1.stderr create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-2.rs create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-2.stderr create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-3.rs create mode 100644 tests/ui/frontmatter/frontmatter-whitespace-4.rs create mode 100644 tests/ui/frontmatter/included-frontmatter.rs create mode 100644 tests/ui/frontmatter/infostring-fail.rs create mode 100644 tests/ui/frontmatter/infostring-fail.stderr create mode 100644 tests/ui/frontmatter/mismatch-1.rs create mode 100644 tests/ui/frontmatter/mismatch-1.stderr create mode 100644 tests/ui/frontmatter/mismatch-2.rs create mode 100644 tests/ui/frontmatter/mismatch-2.stderr create mode 100644 tests/ui/frontmatter/multifrontmatter-2.rs create mode 100644 tests/ui/frontmatter/multifrontmatter-2.stderr create mode 100644 tests/ui/frontmatter/multifrontmatter.rs create mode 100644 tests/ui/frontmatter/multifrontmatter.stderr create mode 100644 tests/ui/frontmatter/proc-macro-observer.rs create mode 100644 tests/ui/frontmatter/shebang.rs create mode 100644 tests/ui/frontmatter/unclosed-1.rs create mode 100644 tests/ui/frontmatter/unclosed-1.stderr create mode 100644 tests/ui/frontmatter/unclosed-2.rs create mode 100644 tests/ui/frontmatter/unclosed-2.stderr create mode 100644 tests/ui/frontmatter/unclosed-3.rs create mode 100644 tests/ui/frontmatter/unclosed-3.stderr create mode 100644 tests/ui/frontmatter/unclosed-4.rs create mode 100644 tests/ui/frontmatter/unclosed-4.stderr create mode 100644 tests/ui/frontmatter/unclosed-5.rs create mode 100644 tests/ui/frontmatter/unclosed-5.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index e312f15f05b0..915613a39137 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -514,6 +514,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(contracts_internals, "contract internal machinery is for internal use only"); gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); gate_all!(super_let, "`super let` is experimental"); + gate_all!(frontmatter, "frontmatters are experimental"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 75e09cacb1f1..f6fddfb4d673 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -506,6 +506,8 @@ declare_features! ( (incomplete, fn_delegation, "1.76.0", Some(118212)), /// Allows impls for the Freeze trait. (internal, freeze_impls, "1.78.0", Some(121675)), + /// Frontmatter `---` blocks for use by external tools. + (unstable, frontmatter, "CURRENT_RUSTC_VERSION", Some(136889)), /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), /// Infer generic args for both consts and types. diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs index e0e3bd0e30b1..526693d3de1f 100644 --- a/compiler/rustc_lexer/src/cursor.rs +++ b/compiler/rustc_lexer/src/cursor.rs @@ -1,5 +1,10 @@ use std::str::Chars; +pub enum FrontmatterAllowed { + Yes, + No, +} + /// Peekable iterator over a char sequence. /// /// Next characters can be peeked via `first` method, @@ -8,6 +13,7 @@ pub struct Cursor<'a> { len_remaining: usize, /// Iterator over chars. Slightly faster than a &str. chars: Chars<'a>, + pub(crate) frontmatter_allowed: FrontmatterAllowed, #[cfg(debug_assertions)] prev: char, } @@ -15,10 +21,11 @@ pub struct Cursor<'a> { pub(crate) const EOF_CHAR: char = '\0'; impl<'a> Cursor<'a> { - pub fn new(input: &'a str) -> Cursor<'a> { + pub fn new(input: &'a str, frontmatter_allowed: FrontmatterAllowed) -> Cursor<'a> { Cursor { len_remaining: input.len(), chars: input.chars(), + frontmatter_allowed, #[cfg(debug_assertions)] prev: EOF_CHAR, } @@ -95,6 +102,11 @@ impl<'a> Cursor<'a> { Some(c) } + /// Moves to a substring by a number of bytes. + pub(crate) fn bump_bytes(&mut self, n: usize) { + self.chars = self.as_str()[n..].chars(); + } + /// Eats symbols while predicate returns true or until the end of file is reached. pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) { // It was tried making optimized version of this for eg. line comments, but diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index f9c71b2fa651..2374f3882509 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -35,8 +35,8 @@ pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION; use self::LiteralKind::*; use self::TokenKind::*; -pub use crate::cursor::Cursor; use crate::cursor::EOF_CHAR; +pub use crate::cursor::{Cursor, FrontmatterAllowed}; /// Parsed token. /// It doesn't contain information about data that has been parsed, @@ -57,17 +57,27 @@ impl Token { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum TokenKind { /// A line comment, e.g. `// comment`. - LineComment { doc_style: Option }, + LineComment { + doc_style: Option, + }, /// A block comment, e.g. `/* block comment */`. /// /// Block comments can be recursive, so a sequence like `/* /* */` /// will not be considered terminated and will result in a parsing error. - BlockComment { doc_style: Option, terminated: bool }, + BlockComment { + doc_style: Option, + terminated: bool, + }, /// Any whitespace character sequence. Whitespace, + Frontmatter { + has_invalid_preceding_whitespace: bool, + invalid_infostring: bool, + }, + /// An identifier or keyword, e.g. `ident` or `continue`. Ident, @@ -109,10 +119,15 @@ pub enum TokenKind { /// this type will need to check for and reject that case. /// /// See [LiteralKind] for more details. - Literal { kind: LiteralKind, suffix_start: u32 }, + Literal { + kind: LiteralKind, + suffix_start: u32, + }, /// A lifetime, e.g. `'a`. - Lifetime { starts_with_number: bool }, + Lifetime { + starts_with_number: bool, + }, /// `;` Semi, @@ -280,7 +295,7 @@ pub fn strip_shebang(input: &str) -> Option { #[inline] pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> { debug_assert!(!input.is_empty()); - let mut cursor = Cursor::new(input); + let mut cursor = Cursor::new(input, FrontmatterAllowed::No); // Move past the leading `r` or `br`. for _ in 0..prefix_len { cursor.bump().unwrap(); @@ -290,7 +305,7 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> /// Creates an iterator that produces tokens from the input string. pub fn tokenize(input: &str) -> impl Iterator { - let mut cursor = Cursor::new(input); + let mut cursor = Cursor::new(input, FrontmatterAllowed::No); std::iter::from_fn(move || { let token = cursor.advance_token(); if token.kind != TokenKind::Eof { Some(token) } else { None } @@ -361,7 +376,34 @@ impl Cursor<'_> { Some(c) => c, None => return Token::new(TokenKind::Eof, 0), }; + let token_kind = match first_char { + c if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes) + && is_whitespace(c) => + { + let mut last = first_char; + while is_whitespace(self.first()) { + let Some(c) = self.bump() else { + break; + }; + last = c; + } + // invalid frontmatter opening as whitespace preceding it isn't newline. + // combine the whitespace and the frontmatter to a single token as we shall + // error later. + if last != '\n' && self.as_str().starts_with("---") { + self.bump(); + self.frontmatter(true) + } else { + Whitespace + } + } + '-' if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes) + && self.as_str().starts_with("--") => + { + // happy path + self.frontmatter(false) + } // Slash, comment or block comment. '/' => match self.first() { '/' => self.line_comment(), @@ -464,11 +506,110 @@ impl Cursor<'_> { c if !c.is_ascii() && c.is_emoji_char() => self.invalid_ident(), _ => Unknown, }; + if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes) + && !matches!(token_kind, Whitespace) + { + // stop allowing frontmatters after first non-whitespace token + self.frontmatter_allowed = FrontmatterAllowed::No; + } let res = Token::new(token_kind, self.pos_within_token()); self.reset_pos_within_token(); res } + /// Given that one `-` was eaten, eat the rest of the frontmatter. + fn frontmatter(&mut self, has_invalid_preceding_whitespace: bool) -> TokenKind { + debug_assert_eq!('-', self.prev()); + + let pos = self.pos_within_token(); + self.eat_while(|c| c == '-'); + + // one `-` is eaten by the caller. + let length_opening = self.pos_within_token() - pos + 1; + + // must be ensured by the caller + debug_assert!(length_opening >= 3); + + // whitespace between the opening and the infostring. + self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + + // copied from `eat_identifier`, but allows `.` in infostring to allow something like + // `---Cargo.toml` as a valid opener + if is_id_start(self.first()) { + self.bump(); + self.eat_while(|c| is_id_continue(c) || c == '.'); + } + + self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + let invalid_infostring = self.first() != '\n'; + + let mut s = self.as_str(); + let mut found = false; + while let Some(closing) = s.find(&"-".repeat(length_opening as usize)) { + let preceding_chars_start = s[..closing].rfind("\n").map_or(0, |i| i + 1); + if s[preceding_chars_start..closing].chars().all(is_whitespace) { + // candidate found + self.bump_bytes(closing); + // in case like + // ---cargo + // --- blahblah + // or + // ---cargo + // ---- + // combine those stuff into this frontmatter token such that it gets detected later. + self.eat_until(b'\n'); + found = true; + break; + } else { + s = &s[closing + length_opening as usize..]; + } + } + + if !found { + // recovery strategy: a closing statement might have precending whitespace/newline + // but not have enough dashes to properly close. In this case, we eat until there, + // and report a mismatch in the parser. + let mut rest = self.as_str(); + // We can look for a shorter closing (starting with four dashes but closing with three) + // and other indications that Rust has started and the infostring has ended. + let mut potential_closing = rest + .find("\n---") + // n.b. only in the case where there are dashes, we move the index to the line where + // the dashes start as we eat to include that line. For other cases those are Rust code + // and not included in the frontmatter. + .map(|x| x + 1) + .or_else(|| rest.find("\nuse ")) + .or_else(|| rest.find("\n//!")) + .or_else(|| rest.find("\n#![")); + + if potential_closing.is_none() { + // a less fortunate recovery if all else fails which finds any dashes preceded by whitespace + // on a standalone line. Might be wrong. + while let Some(closing) = rest.find("---") { + let preceding_chars_start = rest[..closing].rfind("\n").map_or(0, |i| i + 1); + if rest[preceding_chars_start..closing].chars().all(is_whitespace) { + // candidate found + potential_closing = Some(closing); + break; + } else { + rest = &rest[closing + 3..]; + } + } + } + + if let Some(potential_closing) = potential_closing { + // bump to the potential closing, and eat everything on that line. + self.bump_bytes(potential_closing); + self.eat_until(b'\n'); + } else { + // eat everything. this will get reported as an unclosed frontmatter. + self.eat_while(|_| true); + } + } + + Frontmatter { has_invalid_preceding_whitespace, invalid_infostring } + } + fn line_comment(&mut self) -> TokenKind { debug_assert!(self.prev() == '/' && self.first() == '/'); self.bump(); diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index 8203ae70b070..fc8d9b9d57bc 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -4,7 +4,7 @@ use super::*; fn check_raw_str(s: &str, expected: Result) { let s = &format!("r{}", s); - let mut cursor = Cursor::new(s); + let mut cursor = Cursor::new(s, FrontmatterAllowed::No); cursor.bump(); let res = cursor.raw_double_quoted_string(0); assert_eq!(res, expected); diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index ac4f7ed64e22..3e953e6c8555 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -297,6 +297,19 @@ parse_forgot_paren = perhaps you forgot parentheses? parse_found_expr_would_be_stmt = expected expression, found `{$token}` .label = expected expression +parse_frontmatter_extra_characters_after_close = extra characters after frontmatter close are not allowed +parse_frontmatter_invalid_close_preceding_whitespace = invalid preceding whitespace for frontmatter close + .note = frontmatter close should not be preceded by whitespace +parse_frontmatter_invalid_infostring = invalid infostring for frontmatter + .note = frontmatter infostrings must be a single identifier immediately following the opening +parse_frontmatter_invalid_opening_preceding_whitespace = invalid preceding whitespace for frontmatter opening + .note = frontmatter opening should not be preceded by whitespace +parse_frontmatter_length_mismatch = frontmatter close does not match the opening + .label_opening = the opening here has {$len_opening} dashes... + .label_close = ...while the close has {$len_close} dashes +parse_frontmatter_unclosed = unclosed frontmatter + .note = frontmatter opening here was not closed + parse_function_body_equals_expr = function body cannot be `= expression;` .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 6a6fb0eb9b5b..9e5c81d44a56 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -735,6 +735,61 @@ pub(crate) struct FoundExprWouldBeStmt { pub suggestion: ExprParenthesesNeeded, } +#[derive(Diagnostic)] +#[diag(parse_frontmatter_extra_characters_after_close)] +pub(crate) struct FrontmatterExtraCharactersAfterClose { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_frontmatter_invalid_infostring)] +#[note] +pub(crate) struct FrontmatterInvalidInfostring { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_frontmatter_invalid_opening_preceding_whitespace)] +pub(crate) struct FrontmatterInvalidOpeningPrecedingWhitespace { + #[primary_span] + pub span: Span, + #[note] + pub note_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_frontmatter_unclosed)] +pub(crate) struct FrontmatterUnclosed { + #[primary_span] + pub span: Span, + #[note] + pub note_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_frontmatter_invalid_close_preceding_whitespace)] +pub(crate) struct FrontmatterInvalidClosingPrecedingWhitespace { + #[primary_span] + pub span: Span, + #[note] + pub note_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_frontmatter_length_mismatch)] +pub(crate) struct FrontmatterLengthMismatch { + #[primary_span] + pub span: Span, + #[label(parse_label_opening)] + pub opening: Span, + #[label(parse_label_close)] + pub close: Span, + pub len_opening: usize, + pub len_close: usize, +} + #[derive(Diagnostic)] #[diag(parse_leading_plus_not_supported)] pub(crate) struct LeadingPlusNotSupported { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index e8a5cae54cf8..78c5742414b8 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -7,7 +7,9 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::unicode::contains_text_flow_control_chars; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, StashKey}; -use rustc_lexer::{Base, Cursor, DocStyle, LiteralKind, RawStrError}; +use rustc_lexer::{ + Base, Cursor, DocStyle, FrontmatterAllowed, LiteralKind, RawStrError, is_whitespace, +}; use rustc_literal_escaper::{EscapeError, Mode, unescape_mixed, unescape_unicode}; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ @@ -15,7 +17,7 @@ use rustc_session::lint::builtin::{ TEXT_DIRECTION_CODEPOINT_IN_COMMENT, }; use rustc_session::parse::ParseSess; -use rustc_span::{BytePos, Pos, Span, Symbol}; +use rustc_span::{BytePos, Pos, Span, Symbol, sym}; use tracing::debug; use crate::errors; @@ -56,7 +58,7 @@ pub(crate) fn lex_token_trees<'psess, 'src>( start_pos = start_pos + BytePos::from_usize(shebang_len); } - let cursor = Cursor::new(src); + let cursor = Cursor::new(src, FrontmatterAllowed::Yes); let mut lexer = Lexer { psess, start_pos, @@ -193,6 +195,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let content = self.str_from_to(content_start, content_end); self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style) } + rustc_lexer::TokenKind::Frontmatter { has_invalid_preceding_whitespace, invalid_infostring } => { + self.validate_frontmatter(start, has_invalid_preceding_whitespace, invalid_infostring); + preceded_by_whitespace = true; + continue; + } rustc_lexer::TokenKind::Whitespace => { preceded_by_whitespace = true; continue; @@ -256,7 +263,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // was consumed. let lit_start = start + BytePos(prefix_len); self.pos = lit_start; - self.cursor = Cursor::new(&str_before[prefix_len as usize..]); + self.cursor = Cursor::new(&str_before[prefix_len as usize..], FrontmatterAllowed::No); self.report_unknown_prefix(start); let prefix_span = self.mk_sp(start, lit_start); return (Token::new(self.ident(start), prefix_span), preceded_by_whitespace); @@ -361,7 +368,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // Reset the state so we just lex the `'r`. let lt_start = start + BytePos(2); self.pos = lt_start; - self.cursor = Cursor::new(&str_before[2 as usize..]); + self.cursor = Cursor::new(&str_before[2 as usize..], FrontmatterAllowed::No); let lifetime_name = self.str_from(start); let ident = Symbol::intern(lifetime_name); @@ -474,6 +481,91 @@ impl<'psess, 'src> Lexer<'psess, 'src> { } } + fn validate_frontmatter( + &self, + start: BytePos, + has_invalid_preceding_whitespace: bool, + invalid_infostring: bool, + ) { + let s = self.str_from(start); + let real_start = s.find("---").unwrap(); + let frontmatter_opening_pos = BytePos(real_start as u32) + start; + let s_new = &s[real_start..]; + let within = s_new.trim_start_matches('-'); + let len_opening = s_new.len() - within.len(); + + let frontmatter_opening_end_pos = frontmatter_opening_pos + BytePos(len_opening as u32); + if has_invalid_preceding_whitespace { + let line_start = + BytePos(s[..real_start].rfind("\n").map_or(0, |i| i as u32 + 1)) + start; + let span = self.mk_sp(line_start, frontmatter_opening_end_pos); + let label_span = self.mk_sp(line_start, frontmatter_opening_pos); + self.dcx().emit_err(errors::FrontmatterInvalidOpeningPrecedingWhitespace { + span, + note_span: label_span, + }); + } + + if invalid_infostring { + let line_end = s[real_start..].find('\n').unwrap_or(s[real_start..].len()); + let span = self.mk_sp( + frontmatter_opening_end_pos, + frontmatter_opening_pos + BytePos(line_end as u32), + ); + self.dcx().emit_err(errors::FrontmatterInvalidInfostring { span }); + } + + let last_line_start = within.rfind('\n').map_or(0, |i| i + 1); + let last_line = &within[last_line_start..]; + let last_line_trimmed = last_line.trim_start_matches(is_whitespace); + let last_line_start_pos = frontmatter_opening_end_pos + BytePos(last_line_start as u32); + + let frontmatter_span = self.mk_sp(frontmatter_opening_pos, self.pos); + self.psess.gated_spans.gate(sym::frontmatter, frontmatter_span); + + if !last_line_trimmed.starts_with("---") { + let label_span = self.mk_sp(frontmatter_opening_pos, frontmatter_opening_end_pos); + self.dcx().emit_err(errors::FrontmatterUnclosed { + span: frontmatter_span, + note_span: label_span, + }); + return; + } + + if last_line_trimmed.len() != last_line.len() { + let line_end = last_line_start_pos + BytePos(last_line.len() as u32); + let span = self.mk_sp(last_line_start_pos, line_end); + let whitespace_end = + last_line_start_pos + BytePos((last_line.len() - last_line_trimmed.len()) as u32); + let label_span = self.mk_sp(last_line_start_pos, whitespace_end); + self.dcx().emit_err(errors::FrontmatterInvalidClosingPrecedingWhitespace { + span, + note_span: label_span, + }); + } + + let rest = last_line_trimmed.trim_start_matches('-'); + let len_close = last_line_trimmed.len() - rest.len(); + if len_close != len_opening { + let span = self.mk_sp(frontmatter_opening_pos, self.pos); + let opening = self.mk_sp(frontmatter_opening_pos, frontmatter_opening_end_pos); + let last_line_close_pos = last_line_start_pos + BytePos(len_close as u32); + let close = self.mk_sp(last_line_start_pos, last_line_close_pos); + self.dcx().emit_err(errors::FrontmatterLengthMismatch { + span, + opening, + close, + len_opening, + len_close, + }); + } + + if !rest.trim_matches(is_whitespace).is_empty() { + let span = self.mk_sp(last_line_start_pos, self.pos); + self.dcx().emit_err(errors::FrontmatterExtraCharactersAfterClose { span }); + } + } + fn cook_doc_comment( &self, content_start: BytePos, @@ -839,7 +931,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let space_pos = start + BytePos(1); let space_span = self.mk_sp(space_pos, space_pos); - let mut cursor = Cursor::new(str_before); + let mut cursor = Cursor::new(str_before, FrontmatterAllowed::No); let (is_string, span, unterminated) = match cursor.guarded_double_quoted_string() { Some(rustc_lexer::GuardedStr { n_hashes, terminated, token_len }) => { @@ -905,7 +997,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // For backwards compatibility, roll back to after just the first `#` // and return the `Pound` token. self.pos = start + BytePos(1); - self.cursor = Cursor::new(&str_before[1..]); + self.cursor = Cursor::new(&str_before[1..], FrontmatterAllowed::No); token::Pound } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ba3e6d7ca826..d7dbdf04a8c3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1047,6 +1047,7 @@ symbols! { from_u16, from_usize, from_yeet, + frontmatter, fs_create_dir, fsub_algebraic, fsub_fast, diff --git a/src/doc/unstable-book/src/language-features/arbitrary-self-types.md b/src/doc/unstable-book/src/language-features/arbitrary-self-types.md index 2f8b52d40439..d660dd13fe47 100644 --- a/src/doc/unstable-book/src/language-features/arbitrary-self-types.md +++ b/src/doc/unstable-book/src/language-features/arbitrary-self-types.md @@ -2,7 +2,7 @@ The tracking issue for this feature is: [#44874] -[#38788]: https://github.com/rust-lang/rust/issues/44874 +[#44874]: https://github.com/rust-lang/rust/issues/44874 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/f128.md b/src/doc/unstable-book/src/language-features/f128.md index 0cc5f6772302..b523ffe10f25 100644 --- a/src/doc/unstable-book/src/language-features/f128.md +++ b/src/doc/unstable-book/src/language-features/f128.md @@ -6,4 +6,4 @@ The tracking issue for this feature is: [#116909] --- -Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). +Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). diff --git a/src/doc/unstable-book/src/language-features/f16.md b/src/doc/unstable-book/src/language-features/f16.md index efb07a5146d4..5f31dcbb06c0 100644 --- a/src/doc/unstable-book/src/language-features/f16.md +++ b/src/doc/unstable-book/src/language-features/f16.md @@ -6,4 +6,4 @@ The tracking issue for this feature is: [#116909] --- -Enable the `f16` type for IEEE 16-bit floating numbers (half precision). +Enable the `f16` type for IEEE 16-bit floating numbers (half precision). diff --git a/src/doc/unstable-book/src/language-features/frontmatter.md b/src/doc/unstable-book/src/language-features/frontmatter.md new file mode 100644 index 000000000000..1d5b4feb6ac1 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/frontmatter.md @@ -0,0 +1,25 @@ +# `frontmatter` + +The tracking issue for this feature is: [#136889] + +------ + +The `frontmatter` feature allows an extra metadata block at the top of files for consumption by +external tools. For example, it can be used by [`cargo-script`] files to specify dependencies. + +```rust +#!/usr/bin/env -S cargo -Zscript +--- +[dependencies] +libc = "0.2.172" +--- +#![feature(frontmatter)] +# mod libc { pub type c_int = i32; } + +fn main() { + let x: libc::c_int = 1i32; +} +``` + +[#136889]: https://github.com/rust-lang/rust/issues/136889 +[`cargo-script`]: https://rust-lang.github.io/rfcs/3502-cargo-script.html diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c943d3ad4d05..2db1ea8450ce 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -9,7 +9,7 @@ use std::collections::VecDeque; use std::fmt::{Display, Write}; use rustc_data_structures::fx::FxIndexMap; -use rustc_lexer::{Cursor, LiteralKind, TokenKind}; +use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind}; use rustc_span::edition::Edition; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, DUMMY_SP, Span}; @@ -638,7 +638,8 @@ impl<'src> Classifier<'src> { /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code /// file span which will be used later on by the `span_correspondence_map`. fn new(src: &'src str, file_span: Span, decoration_info: Option<&DecorationInfo>) -> Self { - let tokens = PeekIter::new(TokenIter { src, cursor: Cursor::new(src) }); + let tokens = + PeekIter::new(TokenIter { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) }); let decorations = decoration_info.map(Decorations::new); Classifier { tokens, @@ -884,6 +885,7 @@ impl<'src> Classifier<'src> { | TokenKind::At | TokenKind::Tilde | TokenKind::Colon + | TokenKind::Frontmatter { .. } | TokenKind::Unknown => return no_highlight(sink), TokenKind::Question => Class::QuestionMark, diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 585e7ffb1aef..0a5c16dc4c49 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -179,6 +179,15 @@ impl<'a> Converter<'a> { COMMENT } + rustc_lexer::TokenKind::Frontmatter { has_invalid_preceding_whitespace, invalid_infostring } => { + if *has_invalid_preceding_whitespace { + err = "invalid preceding whitespace for frontmatter opening" + } else if *invalid_infostring { + err = "invalid infostring for frontmatter" + } + FRONTMATTER + } + rustc_lexer::TokenKind::Whitespace => WHITESPACE, rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE, diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index e6f93a1fbda5..b1727509b137 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -150,6 +150,7 @@ pub enum SyntaxKind { STRING, COMMENT, ERROR, + FRONTMATTER, IDENT, LIFETIME_IDENT, NEWLINE, @@ -483,6 +484,7 @@ impl SyntaxKind { | YIELD_EXPR | COMMENT | ERROR + | FRONTMATTER | IDENT | LIFETIME_IDENT | NEWLINE @@ -994,7 +996,7 @@ impl SyntaxKind { } } #[macro_export] -macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; [frontmatter] => { $ crate :: SyntaxKind :: FRONTMATTER } ; } impl ::core::marker::Copy for SyntaxKind {} impl ::core::clone::Clone for SyntaxKind { #[inline] diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index a0ae0d68581a..10abca7d35d9 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -133,6 +133,7 @@ Meta = SourceFile = '#shebang'? + '#frontmatter'? Attr* Item* diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 1243f6418fe2..cd9f4dba8908 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -1524,6 +1524,10 @@ impl ast::HasAttrs for SourceFile {} impl ast::HasDocComments for SourceFile {} impl ast::HasModuleItem for SourceFile {} impl SourceFile { + #[inline] + pub fn frontmatter_token(&self) -> Option { + support::token(&self.syntax, T![frontmatter]) + } #[inline] pub fn shebang_token(&self) -> Option { support::token(&self.syntax, T![shebang]) } } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 82df78c1a898..b5350de2b517 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -670,6 +670,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String { [ident] => { $crate::SyntaxKind::IDENT }; [string] => { $crate::SyntaxKind::STRING }; [shebang] => { $crate::SyntaxKind::SHEBANG }; + [frontmatter] => { $crate::SyntaxKind::FRONTMATTER }; } impl ::core::marker::Copy for SyntaxKind {} diff --git a/tests/ui/feature-gates/feature-gate-frontmatter.rs b/tests/ui/feature-gates/feature-gate-frontmatter.rs new file mode 100644 index 000000000000..58e1f57eec02 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-frontmatter.rs @@ -0,0 +1,5 @@ +---cargo +//~^ ERROR: frontmatters are experimental +--- + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-frontmatter.stderr b/tests/ui/feature-gates/feature-gate-frontmatter.stderr new file mode 100644 index 000000000000..57d38db8e76a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-frontmatter.stderr @@ -0,0 +1,15 @@ +error[E0658]: frontmatters are experimental + --> $DIR/feature-gate-frontmatter.rs:1:1 + | +LL | / ---cargo +LL | | +LL | | --- + | |___^ + | + = note: see issue #136889 for more information + = help: add `#![feature(frontmatter)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/frontmatter/auxiliary/lib.rs b/tests/ui/frontmatter/auxiliary/lib.rs new file mode 100644 index 000000000000..ff7094f410f5 --- /dev/null +++ b/tests/ui/frontmatter/auxiliary/lib.rs @@ -0,0 +1,6 @@ +---something +--- + +pub fn foo(x: i32) -> i32 { + -x +} diff --git a/tests/ui/frontmatter/auxiliary/makro.rs b/tests/ui/frontmatter/auxiliary/makro.rs new file mode 100644 index 000000000000..78e7417afb5f --- /dev/null +++ b/tests/ui/frontmatter/auxiliary/makro.rs @@ -0,0 +1,8 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn check(_: TokenStream) -> TokenStream { + assert!("---\n---".parse::().unwrap().is_empty()); + Default::default() +} diff --git a/tests/ui/frontmatter/dot-in-infostring-leading.rs b/tests/ui/frontmatter/dot-in-infostring-leading.rs new file mode 100644 index 000000000000..0d3d699644e9 --- /dev/null +++ b/tests/ui/frontmatter/dot-in-infostring-leading.rs @@ -0,0 +1,9 @@ +---.toml +//~^ ERROR: invalid infostring for frontmatter +--- + +// infostrings cannot have leading dots + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/dot-in-infostring-leading.stderr b/tests/ui/frontmatter/dot-in-infostring-leading.stderr new file mode 100644 index 000000000000..bc86bd80eece --- /dev/null +++ b/tests/ui/frontmatter/dot-in-infostring-leading.stderr @@ -0,0 +1,10 @@ +error: invalid infostring for frontmatter + --> $DIR/dot-in-infostring-leading.rs:1:4 + | +LL | ---.toml + | ^^^^^ + | + = note: frontmatter infostrings must be a single identifier immediately following the opening + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/dot-in-infostring-non-leading.rs b/tests/ui/frontmatter/dot-in-infostring-non-leading.rs new file mode 100644 index 000000000000..a4d17bb6e813 --- /dev/null +++ b/tests/ui/frontmatter/dot-in-infostring-non-leading.rs @@ -0,0 +1,9 @@ +---Cargo.toml +--- + +// infostrings can contain dots as long as a dot isn't the first character. +//@ check-pass + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/escape.rs b/tests/ui/frontmatter/escape.rs new file mode 100644 index 000000000000..0e6f064607e8 --- /dev/null +++ b/tests/ui/frontmatter/escape.rs @@ -0,0 +1,14 @@ +---- + +--- + +---- + +//@ check-pass + +// This test checks that longer dashes for opening and closing can be used to +// escape sequences such as three dashes inside the frontmatter block. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/extra-after-end.rs b/tests/ui/frontmatter/extra-after-end.rs new file mode 100644 index 000000000000..de2cf4cc85ef --- /dev/null +++ b/tests/ui/frontmatter/extra-after-end.rs @@ -0,0 +1,7 @@ +--- +---cargo +//~^ ERROR: extra characters after frontmatter close are not allowed + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/extra-after-end.stderr b/tests/ui/frontmatter/extra-after-end.stderr new file mode 100644 index 000000000000..c2770fdfd41f --- /dev/null +++ b/tests/ui/frontmatter/extra-after-end.stderr @@ -0,0 +1,8 @@ +error: extra characters after frontmatter close are not allowed + --> $DIR/extra-after-end.rs:2:1 + | +LL | ---cargo + | ^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/frontmatter-after-tokens.rs b/tests/ui/frontmatter/frontmatter-after-tokens.rs new file mode 100644 index 000000000000..6683991dc4af --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-after-tokens.rs @@ -0,0 +1,10 @@ +#![feature(frontmatter)] + +--- +//~^ ERROR: expected item, found `-` +// FIXME(frontmatter): make this diagnostic better +--- + +// frontmatters must be at the start of a file. This test ensures that. + +fn main() {} diff --git a/tests/ui/frontmatter/frontmatter-after-tokens.stderr b/tests/ui/frontmatter/frontmatter-after-tokens.stderr new file mode 100644 index 000000000000..919456924d02 --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-after-tokens.stderr @@ -0,0 +1,10 @@ +error: expected item, found `-` + --> $DIR/frontmatter-after-tokens.rs:3:1 + | +LL | --- + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs b/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs new file mode 100644 index 000000000000..ea042edef06b --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs @@ -0,0 +1,12 @@ +---uwu +🏳️‍⚧️ +--- + +//@ check-pass + +#![feature(frontmatter)] + +// check that frontmatter blocks can have tokens that are otherwise not accepted by +// the lexer as Rust code. + +fn main() {} diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.rs b/tests/ui/frontmatter/frontmatter-whitespace-1.rs new file mode 100644 index 000000000000..8b6e2d1af849 --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-1.rs @@ -0,0 +1,10 @@ + --- +//~^ ERROR: invalid preceding whitespace for frontmatter opening + --- +//~^ ERROR: invalid preceding whitespace for frontmatter close + +#![feature(frontmatter)] + +// check that whitespaces should not precede the frontmatter opening or close. + +fn main() {} diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.stderr b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr new file mode 100644 index 000000000000..37ece27acb22 --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr @@ -0,0 +1,26 @@ +error: invalid preceding whitespace for frontmatter opening + --> $DIR/frontmatter-whitespace-1.rs:1:1 + | +LL | --- + | ^^^^^ + | +note: frontmatter opening should not be preceded by whitespace + --> $DIR/frontmatter-whitespace-1.rs:1:1 + | +LL | --- + | ^^ + +error: invalid preceding whitespace for frontmatter close + --> $DIR/frontmatter-whitespace-1.rs:3:1 + | +LL | --- + | ^^^^^ + | +note: frontmatter close should not be preceded by whitespace + --> $DIR/frontmatter-whitespace-1.rs:3:1 + | +LL | --- + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.rs b/tests/ui/frontmatter/frontmatter-whitespace-2.rs new file mode 100644 index 000000000000..e8c100849b40 --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-2.rs @@ -0,0 +1,15 @@ +---cargo + +//@ compile-flags: --crate-type lib + +#![feature(frontmatter)] + +fn foo(x: i32) -> i32 { + ---x + //~^ ERROR: invalid preceding whitespace for frontmatter close + //~| ERROR: extra characters after frontmatter close are not allowed +} +//~^ ERROR: unexpected closing delimiter: `}` + +// this test is for the weird case that valid Rust code can have three dashes +// within them and get treated as a frontmatter close. diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.stderr b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr new file mode 100644 index 000000000000..ada6af0ec04c --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr @@ -0,0 +1,26 @@ +error: invalid preceding whitespace for frontmatter close + --> $DIR/frontmatter-whitespace-2.rs:8:1 + | +LL | ---x + | ^^^^^^^^ + | +note: frontmatter close should not be preceded by whitespace + --> $DIR/frontmatter-whitespace-2.rs:8:1 + | +LL | ---x + | ^^^^ + +error: extra characters after frontmatter close are not allowed + --> $DIR/frontmatter-whitespace-2.rs:8:1 + | +LL | ---x + | ^^^^^^^^ + +error: unexpected closing delimiter: `}` + --> $DIR/frontmatter-whitespace-2.rs:11:1 + | +LL | } + | ^ unexpected closing delimiter + +error: aborting due to 3 previous errors + diff --git a/tests/ui/frontmatter/frontmatter-whitespace-3.rs b/tests/ui/frontmatter/frontmatter-whitespace-3.rs new file mode 100644 index 000000000000..95e0981e2ae8 --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-3.rs @@ -0,0 +1,16 @@ + + +---cargo +--- + +// please note the whitespace characters after the first four lines. +// This ensures that we accept whitespaces before the frontmatter, after +// the frontmatter opening and the frontmatter close. + +//@ check-pass +// ignore-tidy-end-whitespace +// ignore-tidy-leading-newlines + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/frontmatter-whitespace-4.rs b/tests/ui/frontmatter/frontmatter-whitespace-4.rs new file mode 100644 index 000000000000..3bda3227838c --- /dev/null +++ b/tests/ui/frontmatter/frontmatter-whitespace-4.rs @@ -0,0 +1,9 @@ +--- cargo +--- + +//@ check-pass +// A frontmatter infostring can have leading whitespace. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/included-frontmatter.rs b/tests/ui/frontmatter/included-frontmatter.rs new file mode 100644 index 000000000000..57616cd1228c --- /dev/null +++ b/tests/ui/frontmatter/included-frontmatter.rs @@ -0,0 +1,12 @@ +#![feature(frontmatter)] + +//@ check-pass + +include!("auxiliary/lib.rs"); + +// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an +// `include!` macro. + +fn main() { + foo(1); +} diff --git a/tests/ui/frontmatter/infostring-fail.rs b/tests/ui/frontmatter/infostring-fail.rs new file mode 100644 index 000000000000..91542f62f1a5 --- /dev/null +++ b/tests/ui/frontmatter/infostring-fail.rs @@ -0,0 +1,9 @@ +---cargo,clippy +//~^ ERROR: invalid infostring for frontmatter +--- + +// infostrings can only be a single identifier. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/infostring-fail.stderr b/tests/ui/frontmatter/infostring-fail.stderr new file mode 100644 index 000000000000..6b264abc90f1 --- /dev/null +++ b/tests/ui/frontmatter/infostring-fail.stderr @@ -0,0 +1,10 @@ +error: invalid infostring for frontmatter + --> $DIR/infostring-fail.rs:1:4 + | +LL | ---cargo,clippy + | ^^^^^^^^^^^^ + | + = note: frontmatter infostrings must be a single identifier immediately following the opening + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/mismatch-1.rs b/tests/ui/frontmatter/mismatch-1.rs new file mode 100644 index 000000000000..37e2b0af6b18 --- /dev/null +++ b/tests/ui/frontmatter/mismatch-1.rs @@ -0,0 +1,10 @@ +---cargo +//~^ ERROR: frontmatter close does not match the opening +---- + +// there must be the same number of dashes for both the opening and the close +// of the frontmatter. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/mismatch-1.stderr b/tests/ui/frontmatter/mismatch-1.stderr new file mode 100644 index 000000000000..b6e29294d9e1 --- /dev/null +++ b/tests/ui/frontmatter/mismatch-1.stderr @@ -0,0 +1,16 @@ +error: frontmatter close does not match the opening + --> $DIR/mismatch-1.rs:1:1 + | +LL | ---cargo + | ^-- + | | + | _the opening here has 3 dashes... + | | +LL | | +LL | | ---- + | |_---^ + | | + | ...while the close has 4 dashes + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/mismatch-2.rs b/tests/ui/frontmatter/mismatch-2.rs new file mode 100644 index 000000000000..422abe1d6bc9 --- /dev/null +++ b/tests/ui/frontmatter/mismatch-2.rs @@ -0,0 +1,8 @@ +----cargo +//~^ ERROR: frontmatter close does not match the opening +---cargo +//~^ ERROR: extra characters after frontmatter close are not allowed + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/mismatch-2.stderr b/tests/ui/frontmatter/mismatch-2.stderr new file mode 100644 index 000000000000..90bb7b80bcea --- /dev/null +++ b/tests/ui/frontmatter/mismatch-2.stderr @@ -0,0 +1,22 @@ +error: frontmatter close does not match the opening + --> $DIR/mismatch-2.rs:1:1 + | +LL | ----cargo + | ^--- + | | + | _the opening here has 4 dashes... + | | +LL | | +LL | | ---cargo + | |_---____^ + | | + | ...while the close has 3 dashes + +error: extra characters after frontmatter close are not allowed + --> $DIR/mismatch-2.rs:3:1 + | +LL | ---cargo + | ^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/frontmatter/multifrontmatter-2.rs b/tests/ui/frontmatter/multifrontmatter-2.rs new file mode 100644 index 000000000000..33cc30cb4655 --- /dev/null +++ b/tests/ui/frontmatter/multifrontmatter-2.rs @@ -0,0 +1,12 @@ +--- + --- +//~^ ERROR: invalid preceding whitespace for frontmatter close + + --- +//~^ ERROR: expected item, found `-` +// FIXME(frontmatter): make this diagnostic better +--- + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/multifrontmatter-2.stderr b/tests/ui/frontmatter/multifrontmatter-2.stderr new file mode 100644 index 000000000000..ed9ac4029e27 --- /dev/null +++ b/tests/ui/frontmatter/multifrontmatter-2.stderr @@ -0,0 +1,22 @@ +error: invalid preceding whitespace for frontmatter close + --> $DIR/multifrontmatter-2.rs:2:1 + | +LL | --- + | ^^^^ + | +note: frontmatter close should not be preceded by whitespace + --> $DIR/multifrontmatter-2.rs:2:1 + | +LL | --- + | ^ + +error: expected item, found `-` + --> $DIR/multifrontmatter-2.rs:5:2 + | +LL | --- + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 2 previous errors + diff --git a/tests/ui/frontmatter/multifrontmatter.rs b/tests/ui/frontmatter/multifrontmatter.rs new file mode 100644 index 000000000000..f3afa47bd383 --- /dev/null +++ b/tests/ui/frontmatter/multifrontmatter.rs @@ -0,0 +1,13 @@ +--- +--- + +--- +//~^ ERROR: expected item, found `-` +// FIXME(frontmatter): make this diagnostic better +--- + +// test that we do not parse another frontmatter block after the first one. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/multifrontmatter.stderr b/tests/ui/frontmatter/multifrontmatter.stderr new file mode 100644 index 000000000000..2e9d1cee9ddb --- /dev/null +++ b/tests/ui/frontmatter/multifrontmatter.stderr @@ -0,0 +1,10 @@ +error: expected item, found `-` + --> $DIR/multifrontmatter.rs:4:1 + | +LL | --- + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/proc-macro-observer.rs b/tests/ui/frontmatter/proc-macro-observer.rs new file mode 100644 index 000000000000..bafbe912032e --- /dev/null +++ b/tests/ui/frontmatter/proc-macro-observer.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ proc-macro: makro.rs +//@ edition: 2021 + +#![feature(frontmatter)] + +makro::check!(); + +// checks that a proc-macro cannot observe frontmatter tokens. +// see auxiliary/makro.rs for how it is tested. + +fn main() {} diff --git a/tests/ui/frontmatter/shebang.rs b/tests/ui/frontmatter/shebang.rs new file mode 100644 index 000000000000..abd983f219bd --- /dev/null +++ b/tests/ui/frontmatter/shebang.rs @@ -0,0 +1,13 @@ +#!/usr/bin/env -S cargo -Zscript +--- +[dependencies] +clap = "4" +--- + +//@ check-pass + +// Shebangs on a file can precede a frontmatter. + +#![feature(frontmatter)] + +fn main () {} diff --git a/tests/ui/frontmatter/unclosed-1.rs b/tests/ui/frontmatter/unclosed-1.rs new file mode 100644 index 000000000000..d8b52b3e69c7 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-1.rs @@ -0,0 +1,10 @@ +----cargo +//~^ ERROR: unclosed frontmatter + +// This test checks that the #! characters can help us recover a frontmatter +// close. There should not be a "missing `main` function" error as the rest +// are properly parsed. + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/unclosed-1.stderr b/tests/ui/frontmatter/unclosed-1.stderr new file mode 100644 index 000000000000..04031d128398 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-1.stderr @@ -0,0 +1,16 @@ +error: unclosed frontmatter + --> $DIR/unclosed-1.rs:1:1 + | +LL | / ----cargo +... | +LL | | + | |_^ + | +note: frontmatter opening here was not closed + --> $DIR/unclosed-1.rs:1:1 + | +LL | ----cargo + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/unclosed-2.rs b/tests/ui/frontmatter/unclosed-2.rs new file mode 100644 index 000000000000..add266dce5b0 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-2.rs @@ -0,0 +1,15 @@ +----cargo +//~^ ERROR: unclosed frontmatter +//~| ERROR: frontmatters are experimental + +//@ compile-flags: --crate-type lib + +// Leading whitespace on the feature line prevents recovery. However +// the dashes quoted will not be used for recovery and the entire file +// should be treated as within the frontmatter block. + + #![feature(frontmatter)] + +fn foo() -> &str { + "----" +} diff --git a/tests/ui/frontmatter/unclosed-2.stderr b/tests/ui/frontmatter/unclosed-2.stderr new file mode 100644 index 000000000000..0a4022c1557b --- /dev/null +++ b/tests/ui/frontmatter/unclosed-2.stderr @@ -0,0 +1,31 @@ +error: unclosed frontmatter + --> $DIR/unclosed-2.rs:1:1 + | +LL | / ----cargo +... | +LL | | "----" +LL | | } + | |__^ + | +note: frontmatter opening here was not closed + --> $DIR/unclosed-2.rs:1:1 + | +LL | ----cargo + | ^^^^ + +error[E0658]: frontmatters are experimental + --> $DIR/unclosed-2.rs:1:1 + | +LL | / ----cargo +... | +LL | | "----" +LL | | } + | |__^ + | + = note: see issue #136889 for more information + = help: add `#![feature(frontmatter)]` 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 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/frontmatter/unclosed-3.rs b/tests/ui/frontmatter/unclosed-3.rs new file mode 100644 index 000000000000..75f3fbda675c --- /dev/null +++ b/tests/ui/frontmatter/unclosed-3.rs @@ -0,0 +1,16 @@ +----cargo +//~^ ERROR: frontmatter close does not match the opening + +//@ compile-flags: --crate-type lib + +// Unfortunate recovery situation. Not really preventable with improving the +// recovery strategy, but this type of code is rare enough already. + + #![feature(frontmatter)] + +fn foo(x: i32) -> i32 { + ---x + //~^ ERROR: invalid preceding whitespace for frontmatter close + //~| ERROR: extra characters after frontmatter close are not allowed +} +//~^ ERROR: unexpected closing delimiter: `}` diff --git a/tests/ui/frontmatter/unclosed-3.stderr b/tests/ui/frontmatter/unclosed-3.stderr new file mode 100644 index 000000000000..cd69cb000408 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-3.stderr @@ -0,0 +1,41 @@ +error: invalid preceding whitespace for frontmatter close + --> $DIR/unclosed-3.rs:12:1 + | +LL | ---x + | ^^^^^^^^ + | +note: frontmatter close should not be preceded by whitespace + --> $DIR/unclosed-3.rs:12:1 + | +LL | ---x + | ^^^^ + +error: frontmatter close does not match the opening + --> $DIR/unclosed-3.rs:1:1 + | +LL | ----cargo + | ^--- + | | + | _the opening here has 4 dashes... + | | +... | +LL | | fn foo(x: i32) -> i32 { +LL | | ---x + | |_---____^ + | | + | ...while the close has 3 dashes + +error: extra characters after frontmatter close are not allowed + --> $DIR/unclosed-3.rs:12:1 + | +LL | ---x + | ^^^^^^^^ + +error: unexpected closing delimiter: `}` + --> $DIR/unclosed-3.rs:15:1 + | +LL | } + | ^ unexpected closing delimiter + +error: aborting due to 4 previous errors + diff --git a/tests/ui/frontmatter/unclosed-4.rs b/tests/ui/frontmatter/unclosed-4.rs new file mode 100644 index 000000000000..41f6461db634 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-4.rs @@ -0,0 +1,9 @@ +----cargo +//~^ ERROR: unclosed frontmatter + +//! Similarly, a module-level content should allow for recovery as well (as +//! per unclosed-1.rs) + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/unclosed-4.stderr b/tests/ui/frontmatter/unclosed-4.stderr new file mode 100644 index 000000000000..b3ba56937bba --- /dev/null +++ b/tests/ui/frontmatter/unclosed-4.stderr @@ -0,0 +1,16 @@ +error: unclosed frontmatter + --> $DIR/unclosed-4.rs:1:1 + | +LL | / ----cargo +LL | | +LL | | + | |_^ + | +note: frontmatter opening here was not closed + --> $DIR/unclosed-4.rs:1:1 + | +LL | ----cargo + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/frontmatter/unclosed-5.rs b/tests/ui/frontmatter/unclosed-5.rs new file mode 100644 index 000000000000..9abbcfff94c7 --- /dev/null +++ b/tests/ui/frontmatter/unclosed-5.rs @@ -0,0 +1,10 @@ +----cargo +//~^ ERROR: unclosed frontmatter +//~| ERROR: frontmatters are experimental + +// Similarly, a use statement should allow for recovery as well (as +// per unclosed-1.rs) + +use std::env; + +fn main() {} diff --git a/tests/ui/frontmatter/unclosed-5.stderr b/tests/ui/frontmatter/unclosed-5.stderr new file mode 100644 index 000000000000..e904014a175a --- /dev/null +++ b/tests/ui/frontmatter/unclosed-5.stderr @@ -0,0 +1,29 @@ +error: unclosed frontmatter + --> $DIR/unclosed-5.rs:1:1 + | +LL | / ----cargo +... | +LL | | + | |_^ + | +note: frontmatter opening here was not closed + --> $DIR/unclosed-5.rs:1:1 + | +LL | ----cargo + | ^^^^ + +error[E0658]: frontmatters are experimental + --> $DIR/unclosed-5.rs:1:1 + | +LL | / ----cargo +... | +LL | | + | |_^ + | + = note: see issue #136889 for more information + = help: add `#![feature(frontmatter)]` 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 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From cdf4143eb8209926e39a36df244880734bd46a23 Mon Sep 17 00:00:00 2001 From: Vladimir Krivopalov Date: Mon, 3 Mar 2025 12:06:09 -0500 Subject: [PATCH 153/262] Implement `VecDeque::truncate_front()` Tracking issue: #140667 Signed-off-by: Vladimir Krivopalov --- .../alloc/src/collections/vec_deque/mod.rs | 67 ++++++++++++++++++ library/alloctests/tests/lib.rs | 1 + library/alloctests/tests/vec_deque.rs | 69 +++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f8844e2d3a5c..712f38a76c01 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1188,6 +1188,73 @@ impl VecDeque { } } + /// Shortens the deque, keeping the last `len` elements and dropping + /// the rest. + /// + /// If `len` is greater or equal to the deque's current length, this has + /// no effect. + /// + /// # Examples + /// + /// ``` + /// # #![feature(vec_deque_truncate_front)] + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::new(); + /// buf.push_front(5); + /// buf.push_front(10); + /// buf.push_front(15); + /// assert_eq!(buf, [15, 10, 5]); + /// assert_eq!(buf.as_slices(), (&[15, 10, 5][..], &[][..])); + /// buf.truncate_front(1); + /// assert_eq!(buf.as_slices(), (&[5][..], &[][..])); + /// ``` + #[unstable(feature = "vec_deque_truncate_front", issue = "140667")] + pub fn truncate_front(&mut self, len: usize) { + /// Runs the destructor for all items in the slice when it gets dropped (normally or + /// during unwinding). + struct Dropper<'a, T>(&'a mut [T]); + + impl<'a, T> Drop for Dropper<'a, T> { + fn drop(&mut self) { + unsafe { + ptr::drop_in_place(self.0); + } + } + } + + unsafe { + if len >= self.len { + // No action is taken + return; + } + + let (front, back) = self.as_mut_slices(); + if len > back.len() { + // The 'back' slice remains unchanged. + // front.len() + back.len() == self.len, so 'end' is non-negative + // and end < front.len() + let end = front.len() - (len - back.len()); + let drop_front = front.get_unchecked_mut(..end) as *mut _; + self.head += end; + self.len = len; + ptr::drop_in_place(drop_front); + } else { + let drop_front = front as *mut _; + // 'end' is non-negative by the condition above + let end = back.len() - len; + let drop_back = back.get_unchecked_mut(..end) as *mut _; + self.head = self.to_physical_idx(self.len - len); + self.len = len; + + // Make sure the second half is dropped even when a destructor + // in the first one panics. + let _back_dropper = Dropper(&mut *drop_back); + ptr::drop_in_place(drop_front); + } + } + } + /// Returns a reference to the underlying allocator. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index f1f4cc6f93bb..38309585fad6 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -37,6 +37,7 @@ #![feature(str_as_str)] #![feature(strict_provenance_lints)] #![feature(vec_deque_pop_if)] +#![feature(vec_deque_truncate_front)] #![feature(unique_rc_arc)] #![feature(macro_metavar_expr_concat)] #![allow(internal_features)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 1b03c29e5bda..b77ea3a312be 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -1686,6 +1686,40 @@ fn truncate_leak() { assert_eq!(unsafe { DROPS }, 7); } +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn truncate_front_leak() { + static mut DROPS: i32 = 0; + + struct D(bool); + + impl Drop for D { + fn drop(&mut self) { + unsafe { + DROPS += 1; + } + + if self.0 { + panic!("panic in `drop`"); + } + } + } + + let mut q = VecDeque::new(); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_front(D(true)); + q.push_front(D(false)); + q.push_front(D(false)); + + catch_unwind(AssertUnwindSafe(|| q.truncate_front(1))).ok(); + + assert_eq!(unsafe { DROPS }, 7); +} + #[test] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_drain_leak() { @@ -1863,3 +1897,38 @@ fn test_collect_from_into_iter_keeps_allocation() { assert_eq!(v.capacity(), 13); } } + +#[test] +fn test_truncate_front() { + let mut v = VecDeque::with_capacity(13); + v.extend(0..7); + assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.truncate_front(10); + assert_eq!(v.len(), 7); + assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.truncate_front(7); + assert_eq!(v.len(), 7); + assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.truncate_front(3); + assert_eq!(v.as_slices(), ([4, 5, 6].as_slice(), [].as_slice())); + assert_eq!(v.len(), 3); + v.truncate_front(0); + assert_eq!(v.as_slices(), ([].as_slice(), [].as_slice())); + assert_eq!(v.len(), 0); + + v.clear(); + v.extend(0..7); + assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.push_front(9); + v.push_front(8); + v.push_front(7); + assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice())); + v.truncate_front(12); + assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice())); + v.truncate_front(10); + assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice())); + v.truncate_front(8); + assert_eq!(v.as_slices(), ([9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice())); + v.truncate_front(5); + assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice())); +} From b796179f9888b0aff6edf9c393274d9f792a0700 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 15:10:21 +0200 Subject: [PATCH 154/262] Created `tests/rustdoc/reexports` subfolder to limit number of files at the top level --- .../rustdoc/{ => reexport}/alias-reexport.rs | 0 .../rustdoc/{ => reexport}/alias-reexport2.rs | 0 .../anonymous-reexport-108931.rs | 0 .../{ => reexport}/anonymous-reexport.rs | 0 .../auxiliary/alias-reexport.rs | 0 .../auxiliary/alias-reexport2.rs | 0 .../reexport/auxiliary/all-item-types.rs | 22 +++++++++++++++++++ ...ue-113982-doc_auto_cfg-reexport-foreign.rs | 0 .../{ => reexport}/auxiliary/issue-28927-1.rs | 0 .../{ => reexport}/auxiliary/issue-28927-2.rs | 0 .../auxiliary/primitive-reexport.rs | 0 .../auxiliary/reexport-check.rs | 0 .../auxiliary/reexport-doc-aux.rs | 0 .../{ => reexport}/auxiliary/reexports.rs | 0 .../{ => reexport}/blanket-reexport-item.rs | 0 .../{ => reexport}/cfg_doc_reexport.rs | 0 .../doc-hidden-reexports-109449.rs | 0 .../doc_auto_cfg-reexport-foreign-113982.rs | 0 .../duplicated-glob-reexport-60522.rs | 0 .../enum-variant-reexport-35488.rs | 0 .../{ => reexport}/foreigntype-reexport.rs | 0 .../glob-reexport-attribute-merge-120487.rs | 0 ...b-reexport-attribute-merge-doc-auto-cfg.rs | 0 .../ice-reexport-crate-root-28927.rs | 0 .../{ => reexport}/local-reexport-doc.rs | 0 .../{ => reexport}/no-compiler-reexport.rs | 0 .../overlapping-reexport-105735-2.rs | 0 .../overlapping-reexport-105735.rs | 0 .../{ => reexport}/primitive-reexport.rs | 0 .../pub-reexport-of-pub-reexport-46506.rs | 0 .../{ => reexport}/reexport-attr-merge.rs | 0 tests/rustdoc/{ => reexport}/reexport-cfg.rs | 0 .../rustdoc/{ => reexport}/reexport-check.rs | 0 .../{ => reexport}/reexport-dep-foreign-fn.rs | 0 .../reexport-doc-hidden-inside-private.rs | 0 .../{ => reexport}/reexport-doc-hidden.rs | 0 tests/rustdoc/{ => reexport}/reexport-doc.rs | 0 .../{ => reexport}/reexport-hidden-macro.rs | 0 .../rustdoc/{ => reexport}/reexport-macro.rs | 0 .../{ => reexport}/reexport-of-doc-hidden.rs | 0 .../reexport-of-reexport-108679.rs | 0 ...ability-tags-deprecated-and-portability.rs | 0 ...stability-tags-unstable-and-portability.rs | 0 .../reexport-trait-from-hidden-111064-2.rs | 0 .../reexport-trait-from-hidden-111064.rs | 0 .../{ => reexport}/reexports-of-same-name.rs | 0 .../rustdoc/{ => reexport}/reexports-priv.rs | 0 tests/rustdoc/{ => reexport}/reexports.rs | 0 48 files changed, 22 insertions(+) rename tests/rustdoc/{ => reexport}/alias-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/alias-reexport2.rs (100%) rename tests/rustdoc/{ => reexport}/anonymous-reexport-108931.rs (100%) rename tests/rustdoc/{ => reexport}/anonymous-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/alias-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/alias-reexport2.rs (100%) create mode 100644 tests/rustdoc/reexport/auxiliary/all-item-types.rs rename tests/rustdoc/{ => reexport}/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/issue-28927-1.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/issue-28927-2.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/primitive-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/reexport-check.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/reexport-doc-aux.rs (100%) rename tests/rustdoc/{ => reexport}/auxiliary/reexports.rs (100%) rename tests/rustdoc/{ => reexport}/blanket-reexport-item.rs (100%) rename tests/rustdoc/{ => reexport}/cfg_doc_reexport.rs (100%) rename tests/rustdoc/{ => reexport}/doc-hidden-reexports-109449.rs (100%) rename tests/rustdoc/{ => reexport}/doc_auto_cfg-reexport-foreign-113982.rs (100%) rename tests/rustdoc/{ => reexport}/duplicated-glob-reexport-60522.rs (100%) rename tests/rustdoc/{ => reexport}/enum-variant-reexport-35488.rs (100%) rename tests/rustdoc/{ => reexport}/foreigntype-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/glob-reexport-attribute-merge-120487.rs (100%) rename tests/rustdoc/{ => reexport}/glob-reexport-attribute-merge-doc-auto-cfg.rs (100%) rename tests/rustdoc/{ => reexport}/ice-reexport-crate-root-28927.rs (100%) rename tests/rustdoc/{ => reexport}/local-reexport-doc.rs (100%) rename tests/rustdoc/{ => reexport}/no-compiler-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/overlapping-reexport-105735-2.rs (100%) rename tests/rustdoc/{ => reexport}/overlapping-reexport-105735.rs (100%) rename tests/rustdoc/{ => reexport}/primitive-reexport.rs (100%) rename tests/rustdoc/{ => reexport}/pub-reexport-of-pub-reexport-46506.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-attr-merge.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-cfg.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-check.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-dep-foreign-fn.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-doc-hidden-inside-private.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-doc-hidden.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-doc.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-hidden-macro.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-macro.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-of-doc-hidden.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-of-reexport-108679.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-stability-tags-deprecated-and-portability.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-stability-tags-unstable-and-portability.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-trait-from-hidden-111064-2.rs (100%) rename tests/rustdoc/{ => reexport}/reexport-trait-from-hidden-111064.rs (100%) rename tests/rustdoc/{ => reexport}/reexports-of-same-name.rs (100%) rename tests/rustdoc/{ => reexport}/reexports-priv.rs (100%) rename tests/rustdoc/{ => reexport}/reexports.rs (100%) diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/reexport/alias-reexport.rs similarity index 100% rename from tests/rustdoc/alias-reexport.rs rename to tests/rustdoc/reexport/alias-reexport.rs diff --git a/tests/rustdoc/alias-reexport2.rs b/tests/rustdoc/reexport/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/alias-reexport2.rs rename to tests/rustdoc/reexport/alias-reexport2.rs diff --git a/tests/rustdoc/anonymous-reexport-108931.rs b/tests/rustdoc/reexport/anonymous-reexport-108931.rs similarity index 100% rename from tests/rustdoc/anonymous-reexport-108931.rs rename to tests/rustdoc/reexport/anonymous-reexport-108931.rs diff --git a/tests/rustdoc/anonymous-reexport.rs b/tests/rustdoc/reexport/anonymous-reexport.rs similarity index 100% rename from tests/rustdoc/anonymous-reexport.rs rename to tests/rustdoc/reexport/anonymous-reexport.rs diff --git a/tests/rustdoc/auxiliary/alias-reexport.rs b/tests/rustdoc/reexport/auxiliary/alias-reexport.rs similarity index 100% rename from tests/rustdoc/auxiliary/alias-reexport.rs rename to tests/rustdoc/reexport/auxiliary/alias-reexport.rs diff --git a/tests/rustdoc/auxiliary/alias-reexport2.rs b/tests/rustdoc/reexport/auxiliary/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/auxiliary/alias-reexport2.rs rename to tests/rustdoc/reexport/auxiliary/alias-reexport2.rs diff --git a/tests/rustdoc/reexport/auxiliary/all-item-types.rs b/tests/rustdoc/reexport/auxiliary/all-item-types.rs new file mode 100644 index 000000000000..f94bd998717a --- /dev/null +++ b/tests/rustdoc/reexport/auxiliary/all-item-types.rs @@ -0,0 +1,22 @@ +#![feature(extern_types)] + +pub mod foo_mod {} +extern "C" { + pub fn foo_ffn(); + pub static FOO_FSTATIC: FooStruct; + pub type FooFType; +} +pub fn foo_fn() {} +pub trait FooTrait {} +pub struct FooStruct; +pub enum FooEnum {} +pub union FooUnion { + x: (), +} +pub type FooType = FooStruct; +pub static FOO_STATIC: FooStruct = FooStruct; +pub const FOO_CONSTANT: FooStruct = FooStruct; +#[macro_export] +macro_rules! foo_macro { + () => (); +} diff --git a/tests/rustdoc/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs b/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs rename to tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs diff --git a/tests/rustdoc/auxiliary/issue-28927-1.rs b/tests/rustdoc/reexport/auxiliary/issue-28927-1.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-28927-1.rs rename to tests/rustdoc/reexport/auxiliary/issue-28927-1.rs diff --git a/tests/rustdoc/auxiliary/issue-28927-2.rs b/tests/rustdoc/reexport/auxiliary/issue-28927-2.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-28927-2.rs rename to tests/rustdoc/reexport/auxiliary/issue-28927-2.rs diff --git a/tests/rustdoc/auxiliary/primitive-reexport.rs b/tests/rustdoc/reexport/auxiliary/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/auxiliary/primitive-reexport.rs rename to tests/rustdoc/reexport/auxiliary/primitive-reexport.rs diff --git a/tests/rustdoc/auxiliary/reexport-check.rs b/tests/rustdoc/reexport/auxiliary/reexport-check.rs similarity index 100% rename from tests/rustdoc/auxiliary/reexport-check.rs rename to tests/rustdoc/reexport/auxiliary/reexport-check.rs diff --git a/tests/rustdoc/auxiliary/reexport-doc-aux.rs b/tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/reexport-doc-aux.rs rename to tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs diff --git a/tests/rustdoc/auxiliary/reexports.rs b/tests/rustdoc/reexport/auxiliary/reexports.rs similarity index 100% rename from tests/rustdoc/auxiliary/reexports.rs rename to tests/rustdoc/reexport/auxiliary/reexports.rs diff --git a/tests/rustdoc/blanket-reexport-item.rs b/tests/rustdoc/reexport/blanket-reexport-item.rs similarity index 100% rename from tests/rustdoc/blanket-reexport-item.rs rename to tests/rustdoc/reexport/blanket-reexport-item.rs diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/reexport/cfg_doc_reexport.rs similarity index 100% rename from tests/rustdoc/cfg_doc_reexport.rs rename to tests/rustdoc/reexport/cfg_doc_reexport.rs diff --git a/tests/rustdoc/doc-hidden-reexports-109449.rs b/tests/rustdoc/reexport/doc-hidden-reexports-109449.rs similarity index 100% rename from tests/rustdoc/doc-hidden-reexports-109449.rs rename to tests/rustdoc/reexport/doc-hidden-reexports-109449.rs diff --git a/tests/rustdoc/doc_auto_cfg-reexport-foreign-113982.rs b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg-reexport-foreign-113982.rs rename to tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs diff --git a/tests/rustdoc/duplicated-glob-reexport-60522.rs b/tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs similarity index 100% rename from tests/rustdoc/duplicated-glob-reexport-60522.rs rename to tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs diff --git a/tests/rustdoc/enum-variant-reexport-35488.rs b/tests/rustdoc/reexport/enum-variant-reexport-35488.rs similarity index 100% rename from tests/rustdoc/enum-variant-reexport-35488.rs rename to tests/rustdoc/reexport/enum-variant-reexport-35488.rs diff --git a/tests/rustdoc/foreigntype-reexport.rs b/tests/rustdoc/reexport/foreigntype-reexport.rs similarity index 100% rename from tests/rustdoc/foreigntype-reexport.rs rename to tests/rustdoc/reexport/foreigntype-reexport.rs diff --git a/tests/rustdoc/glob-reexport-attribute-merge-120487.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs similarity index 100% rename from tests/rustdoc/glob-reexport-attribute-merge-120487.rs rename to tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs diff --git a/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs rename to tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs diff --git a/tests/rustdoc/ice-reexport-crate-root-28927.rs b/tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs similarity index 100% rename from tests/rustdoc/ice-reexport-crate-root-28927.rs rename to tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs diff --git a/tests/rustdoc/local-reexport-doc.rs b/tests/rustdoc/reexport/local-reexport-doc.rs similarity index 100% rename from tests/rustdoc/local-reexport-doc.rs rename to tests/rustdoc/reexport/local-reexport-doc.rs diff --git a/tests/rustdoc/no-compiler-reexport.rs b/tests/rustdoc/reexport/no-compiler-reexport.rs similarity index 100% rename from tests/rustdoc/no-compiler-reexport.rs rename to tests/rustdoc/reexport/no-compiler-reexport.rs diff --git a/tests/rustdoc/overlapping-reexport-105735-2.rs b/tests/rustdoc/reexport/overlapping-reexport-105735-2.rs similarity index 100% rename from tests/rustdoc/overlapping-reexport-105735-2.rs rename to tests/rustdoc/reexport/overlapping-reexport-105735-2.rs diff --git a/tests/rustdoc/overlapping-reexport-105735.rs b/tests/rustdoc/reexport/overlapping-reexport-105735.rs similarity index 100% rename from tests/rustdoc/overlapping-reexport-105735.rs rename to tests/rustdoc/reexport/overlapping-reexport-105735.rs diff --git a/tests/rustdoc/primitive-reexport.rs b/tests/rustdoc/reexport/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/primitive-reexport.rs rename to tests/rustdoc/reexport/primitive-reexport.rs diff --git a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs similarity index 100% rename from tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs rename to tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport/reexport-attr-merge.rs similarity index 100% rename from tests/rustdoc/reexport-attr-merge.rs rename to tests/rustdoc/reexport/reexport-attr-merge.rs diff --git a/tests/rustdoc/reexport-cfg.rs b/tests/rustdoc/reexport/reexport-cfg.rs similarity index 100% rename from tests/rustdoc/reexport-cfg.rs rename to tests/rustdoc/reexport/reexport-cfg.rs diff --git a/tests/rustdoc/reexport-check.rs b/tests/rustdoc/reexport/reexport-check.rs similarity index 100% rename from tests/rustdoc/reexport-check.rs rename to tests/rustdoc/reexport/reexport-check.rs diff --git a/tests/rustdoc/reexport-dep-foreign-fn.rs b/tests/rustdoc/reexport/reexport-dep-foreign-fn.rs similarity index 100% rename from tests/rustdoc/reexport-dep-foreign-fn.rs rename to tests/rustdoc/reexport/reexport-dep-foreign-fn.rs diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs similarity index 100% rename from tests/rustdoc/reexport-doc-hidden-inside-private.rs rename to tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs diff --git a/tests/rustdoc/reexport-doc-hidden.rs b/tests/rustdoc/reexport/reexport-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport-doc-hidden.rs rename to tests/rustdoc/reexport/reexport-doc-hidden.rs diff --git a/tests/rustdoc/reexport-doc.rs b/tests/rustdoc/reexport/reexport-doc.rs similarity index 100% rename from tests/rustdoc/reexport-doc.rs rename to tests/rustdoc/reexport/reexport-doc.rs diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport/reexport-hidden-macro.rs similarity index 100% rename from tests/rustdoc/reexport-hidden-macro.rs rename to tests/rustdoc/reexport/reexport-hidden-macro.rs diff --git a/tests/rustdoc/reexport-macro.rs b/tests/rustdoc/reexport/reexport-macro.rs similarity index 100% rename from tests/rustdoc/reexport-macro.rs rename to tests/rustdoc/reexport/reexport-macro.rs diff --git a/tests/rustdoc/reexport-of-doc-hidden.rs b/tests/rustdoc/reexport/reexport-of-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport-of-doc-hidden.rs rename to tests/rustdoc/reexport/reexport-of-doc-hidden.rs diff --git a/tests/rustdoc/reexport-of-reexport-108679.rs b/tests/rustdoc/reexport/reexport-of-reexport-108679.rs similarity index 100% rename from tests/rustdoc/reexport-of-reexport-108679.rs rename to tests/rustdoc/reexport/reexport-of-reexport-108679.rs diff --git a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs rename to tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs diff --git a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs rename to tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs similarity index 100% rename from tests/rustdoc/reexport-trait-from-hidden-111064-2.rs rename to tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064.rs b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs similarity index 100% rename from tests/rustdoc/reexport-trait-from-hidden-111064.rs rename to tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs diff --git a/tests/rustdoc/reexports-of-same-name.rs b/tests/rustdoc/reexport/reexports-of-same-name.rs similarity index 100% rename from tests/rustdoc/reexports-of-same-name.rs rename to tests/rustdoc/reexport/reexports-of-same-name.rs diff --git a/tests/rustdoc/reexports-priv.rs b/tests/rustdoc/reexport/reexports-priv.rs similarity index 100% rename from tests/rustdoc/reexports-priv.rs rename to tests/rustdoc/reexport/reexports-priv.rs diff --git a/tests/rustdoc/reexports.rs b/tests/rustdoc/reexport/reexports.rs similarity index 100% rename from tests/rustdoc/reexports.rs rename to tests/rustdoc/reexport/reexports.rs From 099f730dcf95404e3f272cb2690a25077b9f2a4b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 15:21:06 +0200 Subject: [PATCH 155/262] Created `tests/rustdoc/source-code-pages` subfolder to limit number of files at the top level --- tests/rustdoc/{ => source-code-pages}/assoc-type-source-link.rs | 0 .../{ => source-code-pages}/auxiliary/issue-26606-macro.rs | 0 tests/rustdoc/{ => source-code-pages}/auxiliary/issue-34274.rs | 0 .../rustdoc/{ => source-code-pages}/auxiliary/source-code-bar.rs | 0 tests/rustdoc/{ => source-code-pages}/auxiliary/source_code.rs | 0 .../{ => source-code-pages}/auxiliary/src-links-external.rs | 0 .../{ => source-code-pages}/check-source-code-urls-to-def-std.rs | 0 .../{ => source-code-pages}/check-source-code-urls-to-def.rs | 0 tests/rustdoc/{ => source-code-pages}/doc-hidden-source.rs | 0 tests/rustdoc/{ => source-code-pages}/html-no-source.rs | 0 tests/rustdoc/{ => source-code-pages}/source-code-highlight.rs | 0 tests/rustdoc/{ => source-code-pages}/source-file.rs | 0 tests/rustdoc/{ => source-code-pages}/source-line-numbers.rs | 0 tests/rustdoc/{ => source-code-pages}/source-version-separator.rs | 0 .../{ => source-code-pages}/src-link-external-macro-26606.rs | 0 tests/rustdoc/{ => source-code-pages}/src-links-auto-impls.rs | 0 tests/rustdoc/{ => source-code-pages}/src-links-external.rs | 0 .../{ => source-code-pages}/src-links-implementor-43893.rs | 0 tests/rustdoc/{ => source-code-pages}/src-links-inlined-34274.rs | 0 tests/rustdoc/{ => source-code-pages}/src-links.rs | 0 .../{ => source-code-pages}/src-links/compiletest-ignore-dir | 0 tests/rustdoc/{ => source-code-pages}/src-links/fizz.rs | 0 tests/rustdoc/{ => source-code-pages}/src-links/mod.rs | 0 .../{ => source-code-pages}/src-mod-path-absolute-26995.rs | 0 .../{ => source-code-pages}/version-separator-without-source.rs | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => source-code-pages}/assoc-type-source-link.rs (100%) rename tests/rustdoc/{ => source-code-pages}/auxiliary/issue-26606-macro.rs (100%) rename tests/rustdoc/{ => source-code-pages}/auxiliary/issue-34274.rs (100%) rename tests/rustdoc/{ => source-code-pages}/auxiliary/source-code-bar.rs (100%) rename tests/rustdoc/{ => source-code-pages}/auxiliary/source_code.rs (100%) rename tests/rustdoc/{ => source-code-pages}/auxiliary/src-links-external.rs (100%) rename tests/rustdoc/{ => source-code-pages}/check-source-code-urls-to-def-std.rs (100%) rename tests/rustdoc/{ => source-code-pages}/check-source-code-urls-to-def.rs (100%) rename tests/rustdoc/{ => source-code-pages}/doc-hidden-source.rs (100%) rename tests/rustdoc/{ => source-code-pages}/html-no-source.rs (100%) rename tests/rustdoc/{ => source-code-pages}/source-code-highlight.rs (100%) rename tests/rustdoc/{ => source-code-pages}/source-file.rs (100%) rename tests/rustdoc/{ => source-code-pages}/source-line-numbers.rs (100%) rename tests/rustdoc/{ => source-code-pages}/source-version-separator.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-link-external-macro-26606.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links-auto-impls.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links-external.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links-implementor-43893.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links-inlined-34274.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links/compiletest-ignore-dir (100%) rename tests/rustdoc/{ => source-code-pages}/src-links/fizz.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-links/mod.rs (100%) rename tests/rustdoc/{ => source-code-pages}/src-mod-path-absolute-26995.rs (100%) rename tests/rustdoc/{ => source-code-pages}/version-separator-without-source.rs (100%) diff --git a/tests/rustdoc/assoc-type-source-link.rs b/tests/rustdoc/source-code-pages/assoc-type-source-link.rs similarity index 100% rename from tests/rustdoc/assoc-type-source-link.rs rename to tests/rustdoc/source-code-pages/assoc-type-source-link.rs diff --git a/tests/rustdoc/auxiliary/issue-26606-macro.rs b/tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-26606-macro.rs rename to tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs diff --git a/tests/rustdoc/auxiliary/issue-34274.rs b/tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-34274.rs rename to tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs diff --git a/tests/rustdoc/auxiliary/source-code-bar.rs b/tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs similarity index 100% rename from tests/rustdoc/auxiliary/source-code-bar.rs rename to tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs diff --git a/tests/rustdoc/auxiliary/source_code.rs b/tests/rustdoc/source-code-pages/auxiliary/source_code.rs similarity index 100% rename from tests/rustdoc/auxiliary/source_code.rs rename to tests/rustdoc/source-code-pages/auxiliary/source_code.rs diff --git a/tests/rustdoc/auxiliary/src-links-external.rs b/tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs similarity index 100% rename from tests/rustdoc/auxiliary/src-links-external.rs rename to tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs diff --git a/tests/rustdoc/check-source-code-urls-to-def-std.rs b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs similarity index 100% rename from tests/rustdoc/check-source-code-urls-to-def-std.rs rename to tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs diff --git a/tests/rustdoc/check-source-code-urls-to-def.rs b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs similarity index 100% rename from tests/rustdoc/check-source-code-urls-to-def.rs rename to tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs diff --git a/tests/rustdoc/doc-hidden-source.rs b/tests/rustdoc/source-code-pages/doc-hidden-source.rs similarity index 100% rename from tests/rustdoc/doc-hidden-source.rs rename to tests/rustdoc/source-code-pages/doc-hidden-source.rs diff --git a/tests/rustdoc/html-no-source.rs b/tests/rustdoc/source-code-pages/html-no-source.rs similarity index 100% rename from tests/rustdoc/html-no-source.rs rename to tests/rustdoc/source-code-pages/html-no-source.rs diff --git a/tests/rustdoc/source-code-highlight.rs b/tests/rustdoc/source-code-pages/source-code-highlight.rs similarity index 100% rename from tests/rustdoc/source-code-highlight.rs rename to tests/rustdoc/source-code-pages/source-code-highlight.rs diff --git a/tests/rustdoc/source-file.rs b/tests/rustdoc/source-code-pages/source-file.rs similarity index 100% rename from tests/rustdoc/source-file.rs rename to tests/rustdoc/source-code-pages/source-file.rs diff --git a/tests/rustdoc/source-line-numbers.rs b/tests/rustdoc/source-code-pages/source-line-numbers.rs similarity index 100% rename from tests/rustdoc/source-line-numbers.rs rename to tests/rustdoc/source-code-pages/source-line-numbers.rs diff --git a/tests/rustdoc/source-version-separator.rs b/tests/rustdoc/source-code-pages/source-version-separator.rs similarity index 100% rename from tests/rustdoc/source-version-separator.rs rename to tests/rustdoc/source-code-pages/source-version-separator.rs diff --git a/tests/rustdoc/src-link-external-macro-26606.rs b/tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs similarity index 100% rename from tests/rustdoc/src-link-external-macro-26606.rs rename to tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs diff --git a/tests/rustdoc/src-links-auto-impls.rs b/tests/rustdoc/source-code-pages/src-links-auto-impls.rs similarity index 100% rename from tests/rustdoc/src-links-auto-impls.rs rename to tests/rustdoc/source-code-pages/src-links-auto-impls.rs diff --git a/tests/rustdoc/src-links-external.rs b/tests/rustdoc/source-code-pages/src-links-external.rs similarity index 100% rename from tests/rustdoc/src-links-external.rs rename to tests/rustdoc/source-code-pages/src-links-external.rs diff --git a/tests/rustdoc/src-links-implementor-43893.rs b/tests/rustdoc/source-code-pages/src-links-implementor-43893.rs similarity index 100% rename from tests/rustdoc/src-links-implementor-43893.rs rename to tests/rustdoc/source-code-pages/src-links-implementor-43893.rs diff --git a/tests/rustdoc/src-links-inlined-34274.rs b/tests/rustdoc/source-code-pages/src-links-inlined-34274.rs similarity index 100% rename from tests/rustdoc/src-links-inlined-34274.rs rename to tests/rustdoc/source-code-pages/src-links-inlined-34274.rs diff --git a/tests/rustdoc/src-links.rs b/tests/rustdoc/source-code-pages/src-links.rs similarity index 100% rename from tests/rustdoc/src-links.rs rename to tests/rustdoc/source-code-pages/src-links.rs diff --git a/tests/rustdoc/src-links/compiletest-ignore-dir b/tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir similarity index 100% rename from tests/rustdoc/src-links/compiletest-ignore-dir rename to tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir diff --git a/tests/rustdoc/src-links/fizz.rs b/tests/rustdoc/source-code-pages/src-links/fizz.rs similarity index 100% rename from tests/rustdoc/src-links/fizz.rs rename to tests/rustdoc/source-code-pages/src-links/fizz.rs diff --git a/tests/rustdoc/src-links/mod.rs b/tests/rustdoc/source-code-pages/src-links/mod.rs similarity index 100% rename from tests/rustdoc/src-links/mod.rs rename to tests/rustdoc/source-code-pages/src-links/mod.rs diff --git a/tests/rustdoc/src-mod-path-absolute-26995.rs b/tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs similarity index 100% rename from tests/rustdoc/src-mod-path-absolute-26995.rs rename to tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs diff --git a/tests/rustdoc/version-separator-without-source.rs b/tests/rustdoc/source-code-pages/version-separator-without-source.rs similarity index 100% rename from tests/rustdoc/version-separator-without-source.rs rename to tests/rustdoc/source-code-pages/version-separator-without-source.rs From b374996ab8d3d8a10fdf1ffcf2b1c3de3fdbbf64 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 15:50:06 +0200 Subject: [PATCH 156/262] Created `tests/rustdoc/anchors` subfolder to limit number of files at the top level --- .../{ => anchors}/anchor-id-duplicate-method-name-25001.rs | 0 tests/rustdoc/{ => anchors}/anchor-id-trait-method-15169.rs | 0 tests/rustdoc/{ => anchors}/anchor-id-trait-tymethod-28478.rs | 0 tests/rustdoc/{ => anchors}/anchors.no_const_anchor.html | 0 tests/rustdoc/{ => anchors}/anchors.no_const_anchor2.html | 0 tests/rustdoc/{ => anchors}/anchors.no_method_anchor.html | 0 tests/rustdoc/{ => anchors}/anchors.no_trait_method_anchor.html | 0 tests/rustdoc/{ => anchors}/anchors.no_tymethod_anchor.html | 0 tests/rustdoc/{ => anchors}/anchors.no_type_anchor.html | 0 tests/rustdoc/{ => anchors}/anchors.no_type_anchor2.html | 0 tests/rustdoc/{ => anchors}/anchors.rs | 0 tests/rustdoc/{ => anchors}/auxiliary/issue-86620-1.rs | 0 tests/rustdoc/{ => anchors}/disambiguate-anchors-32890.rs | 0 tests/rustdoc/{ => anchors}/disambiguate-anchors-header-29449.rs | 0 .../{ => anchors}/extern-default-method.no_href_on_anchor.html | 0 .../rustdoc/{ => anchors}/method-anchor-in-blanket-impl-86620.rs | 0 tests/rustdoc/{ => anchors}/trait-impl-items-links-and-anchors.rs | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => anchors}/anchor-id-duplicate-method-name-25001.rs (100%) rename tests/rustdoc/{ => anchors}/anchor-id-trait-method-15169.rs (100%) rename tests/rustdoc/{ => anchors}/anchor-id-trait-tymethod-28478.rs (100%) rename tests/rustdoc/{ => anchors}/anchors.no_const_anchor.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_const_anchor2.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_method_anchor.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_trait_method_anchor.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_tymethod_anchor.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_type_anchor.html (100%) rename tests/rustdoc/{ => anchors}/anchors.no_type_anchor2.html (100%) rename tests/rustdoc/{ => anchors}/anchors.rs (100%) rename tests/rustdoc/{ => anchors}/auxiliary/issue-86620-1.rs (100%) rename tests/rustdoc/{ => anchors}/disambiguate-anchors-32890.rs (100%) rename tests/rustdoc/{ => anchors}/disambiguate-anchors-header-29449.rs (100%) rename tests/rustdoc/{ => anchors}/extern-default-method.no_href_on_anchor.html (100%) rename tests/rustdoc/{ => anchors}/method-anchor-in-blanket-impl-86620.rs (100%) rename tests/rustdoc/{ => anchors}/trait-impl-items-links-and-anchors.rs (100%) diff --git a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs similarity index 100% rename from tests/rustdoc/anchor-id-duplicate-method-name-25001.rs rename to tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs diff --git a/tests/rustdoc/anchor-id-trait-method-15169.rs b/tests/rustdoc/anchors/anchor-id-trait-method-15169.rs similarity index 100% rename from tests/rustdoc/anchor-id-trait-method-15169.rs rename to tests/rustdoc/anchors/anchor-id-trait-method-15169.rs diff --git a/tests/rustdoc/anchor-id-trait-tymethod-28478.rs b/tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs similarity index 100% rename from tests/rustdoc/anchor-id-trait-tymethod-28478.rs rename to tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs diff --git a/tests/rustdoc/anchors.no_const_anchor.html b/tests/rustdoc/anchors/anchors.no_const_anchor.html similarity index 100% rename from tests/rustdoc/anchors.no_const_anchor.html rename to tests/rustdoc/anchors/anchors.no_const_anchor.html diff --git a/tests/rustdoc/anchors.no_const_anchor2.html b/tests/rustdoc/anchors/anchors.no_const_anchor2.html similarity index 100% rename from tests/rustdoc/anchors.no_const_anchor2.html rename to tests/rustdoc/anchors/anchors.no_const_anchor2.html diff --git a/tests/rustdoc/anchors.no_method_anchor.html b/tests/rustdoc/anchors/anchors.no_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors.no_method_anchor.html rename to tests/rustdoc/anchors/anchors.no_method_anchor.html diff --git a/tests/rustdoc/anchors.no_trait_method_anchor.html b/tests/rustdoc/anchors/anchors.no_trait_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors.no_trait_method_anchor.html rename to tests/rustdoc/anchors/anchors.no_trait_method_anchor.html diff --git a/tests/rustdoc/anchors.no_tymethod_anchor.html b/tests/rustdoc/anchors/anchors.no_tymethod_anchor.html similarity index 100% rename from tests/rustdoc/anchors.no_tymethod_anchor.html rename to tests/rustdoc/anchors/anchors.no_tymethod_anchor.html diff --git a/tests/rustdoc/anchors.no_type_anchor.html b/tests/rustdoc/anchors/anchors.no_type_anchor.html similarity index 100% rename from tests/rustdoc/anchors.no_type_anchor.html rename to tests/rustdoc/anchors/anchors.no_type_anchor.html diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors/anchors.no_type_anchor2.html similarity index 100% rename from tests/rustdoc/anchors.no_type_anchor2.html rename to tests/rustdoc/anchors/anchors.no_type_anchor2.html diff --git a/tests/rustdoc/anchors.rs b/tests/rustdoc/anchors/anchors.rs similarity index 100% rename from tests/rustdoc/anchors.rs rename to tests/rustdoc/anchors/anchors.rs diff --git a/tests/rustdoc/auxiliary/issue-86620-1.rs b/tests/rustdoc/anchors/auxiliary/issue-86620-1.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-86620-1.rs rename to tests/rustdoc/anchors/auxiliary/issue-86620-1.rs diff --git a/tests/rustdoc/disambiguate-anchors-32890.rs b/tests/rustdoc/anchors/disambiguate-anchors-32890.rs similarity index 100% rename from tests/rustdoc/disambiguate-anchors-32890.rs rename to tests/rustdoc/anchors/disambiguate-anchors-32890.rs diff --git a/tests/rustdoc/disambiguate-anchors-header-29449.rs b/tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs similarity index 100% rename from tests/rustdoc/disambiguate-anchors-header-29449.rs rename to tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs diff --git a/tests/rustdoc/extern-default-method.no_href_on_anchor.html b/tests/rustdoc/anchors/extern-default-method.no_href_on_anchor.html similarity index 100% rename from tests/rustdoc/extern-default-method.no_href_on_anchor.html rename to tests/rustdoc/anchors/extern-default-method.no_href_on_anchor.html diff --git a/tests/rustdoc/method-anchor-in-blanket-impl-86620.rs b/tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs similarity index 100% rename from tests/rustdoc/method-anchor-in-blanket-impl-86620.rs rename to tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs diff --git a/tests/rustdoc/trait-impl-items-links-and-anchors.rs b/tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs similarity index 100% rename from tests/rustdoc/trait-impl-items-links-and-anchors.rs rename to tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs From ff971d001d3440fa609f8c5370432c6b77a5ac6e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:28:15 +0200 Subject: [PATCH 157/262] Created `tests/rustdoc/auto` subfolder to limit number of files at the top level --- tests/rustdoc/{ => auto}/auto-impl-for-trait.rs | 0 tests/rustdoc/{ => auto}/auto-impl-primitive.rs | 0 .../{ => auto}/auto-trait-bounds-by-associated-type-50159.rs | 0 .../{ => auto}/auto-trait-bounds-inference-variables-54705.rs | 0 tests/rustdoc/{ => auto}/auto-trait-bounds-where-51236.rs | 0 tests/rustdoc/{ => auto}/auto-trait-negative-impl-55321.rs | 0 tests/rustdoc/{ => auto}/auto-trait-not-send.rs | 0 tests/rustdoc/{ => auto}/auto-traits.rs | 0 tests/rustdoc/{ => auto}/auto_aliases.rs | 0 tests/rustdoc/{ => auto}/auxiliary/auto-traits.rs | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => auto}/auto-impl-for-trait.rs (100%) rename tests/rustdoc/{ => auto}/auto-impl-primitive.rs (100%) rename tests/rustdoc/{ => auto}/auto-trait-bounds-by-associated-type-50159.rs (100%) rename tests/rustdoc/{ => auto}/auto-trait-bounds-inference-variables-54705.rs (100%) rename tests/rustdoc/{ => auto}/auto-trait-bounds-where-51236.rs (100%) rename tests/rustdoc/{ => auto}/auto-trait-negative-impl-55321.rs (100%) rename tests/rustdoc/{ => auto}/auto-trait-not-send.rs (100%) rename tests/rustdoc/{ => auto}/auto-traits.rs (100%) rename tests/rustdoc/{ => auto}/auto_aliases.rs (100%) rename tests/rustdoc/{ => auto}/auxiliary/auto-traits.rs (100%) diff --git a/tests/rustdoc/auto-impl-for-trait.rs b/tests/rustdoc/auto/auto-impl-for-trait.rs similarity index 100% rename from tests/rustdoc/auto-impl-for-trait.rs rename to tests/rustdoc/auto/auto-impl-for-trait.rs diff --git a/tests/rustdoc/auto-impl-primitive.rs b/tests/rustdoc/auto/auto-impl-primitive.rs similarity index 100% rename from tests/rustdoc/auto-impl-primitive.rs rename to tests/rustdoc/auto/auto-impl-primitive.rs diff --git a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs similarity index 100% rename from tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs rename to tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs diff --git a/tests/rustdoc/auto-trait-bounds-inference-variables-54705.rs b/tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs similarity index 100% rename from tests/rustdoc/auto-trait-bounds-inference-variables-54705.rs rename to tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs diff --git a/tests/rustdoc/auto-trait-bounds-where-51236.rs b/tests/rustdoc/auto/auto-trait-bounds-where-51236.rs similarity index 100% rename from tests/rustdoc/auto-trait-bounds-where-51236.rs rename to tests/rustdoc/auto/auto-trait-bounds-where-51236.rs diff --git a/tests/rustdoc/auto-trait-negative-impl-55321.rs b/tests/rustdoc/auto/auto-trait-negative-impl-55321.rs similarity index 100% rename from tests/rustdoc/auto-trait-negative-impl-55321.rs rename to tests/rustdoc/auto/auto-trait-negative-impl-55321.rs diff --git a/tests/rustdoc/auto-trait-not-send.rs b/tests/rustdoc/auto/auto-trait-not-send.rs similarity index 100% rename from tests/rustdoc/auto-trait-not-send.rs rename to tests/rustdoc/auto/auto-trait-not-send.rs diff --git a/tests/rustdoc/auto-traits.rs b/tests/rustdoc/auto/auto-traits.rs similarity index 100% rename from tests/rustdoc/auto-traits.rs rename to tests/rustdoc/auto/auto-traits.rs diff --git a/tests/rustdoc/auto_aliases.rs b/tests/rustdoc/auto/auto_aliases.rs similarity index 100% rename from tests/rustdoc/auto_aliases.rs rename to tests/rustdoc/auto/auto_aliases.rs diff --git a/tests/rustdoc/auxiliary/auto-traits.rs b/tests/rustdoc/auto/auxiliary/auto-traits.rs similarity index 100% rename from tests/rustdoc/auxiliary/auto-traits.rs rename to tests/rustdoc/auto/auxiliary/auto-traits.rs From 9db7de5915314a3924548f2b1645d09ba2644dad Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:31:58 +0200 Subject: [PATCH 158/262] Created `tests/rustdoc/jump-to-def` subfolder to limit number of files at the top level --- tests/rustdoc/{ => jump-to-def}/auxiliary/jump-to-def-macro.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-def-doc-links-calls.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-def-doc-links.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-def-macro.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-def-pats.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-def-prelude-types.rs | 0 tests/rustdoc/{ => jump-to-def}/jump-to-non-local-method.rs | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => jump-to-def}/auxiliary/jump-to-def-macro.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-def-doc-links-calls.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-def-doc-links.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-def-macro.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-def-pats.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-def-prelude-types.rs (100%) rename tests/rustdoc/{ => jump-to-def}/jump-to-non-local-method.rs (100%) diff --git a/tests/rustdoc/auxiliary/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs similarity index 100% rename from tests/rustdoc/auxiliary/jump-to-def-macro.rs rename to tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs diff --git a/tests/rustdoc/jump-to-def-doc-links-calls.rs b/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs similarity index 100% rename from tests/rustdoc/jump-to-def-doc-links-calls.rs rename to tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs diff --git a/tests/rustdoc/jump-to-def-doc-links.rs b/tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs similarity index 100% rename from tests/rustdoc/jump-to-def-doc-links.rs rename to tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs diff --git a/tests/rustdoc/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/jump-to-def-macro.rs similarity index 100% rename from tests/rustdoc/jump-to-def-macro.rs rename to tests/rustdoc/jump-to-def/jump-to-def-macro.rs diff --git a/tests/rustdoc/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def/jump-to-def-pats.rs similarity index 100% rename from tests/rustdoc/jump-to-def-pats.rs rename to tests/rustdoc/jump-to-def/jump-to-def-pats.rs diff --git a/tests/rustdoc/jump-to-def-prelude-types.rs b/tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs similarity index 100% rename from tests/rustdoc/jump-to-def-prelude-types.rs rename to tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs diff --git a/tests/rustdoc/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs similarity index 100% rename from tests/rustdoc/jump-to-non-local-method.rs rename to tests/rustdoc/jump-to-def/jump-to-non-local-method.rs From a00b39961a9b45c788b86ef9f874d886f5403280 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:32:47 +0200 Subject: [PATCH 159/262] Move intra-doc tests into the expected subfolder --- tests/rustdoc/{ => intra-doc}/ice-intra-doc-links-107995.rs | 0 .../{ => intra-doc}/intra-doc-link-method-trait-impl-72340.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => intra-doc}/ice-intra-doc-links-107995.rs (100%) rename tests/rustdoc/{ => intra-doc}/intra-doc-link-method-trait-impl-72340.rs (100%) diff --git a/tests/rustdoc/ice-intra-doc-links-107995.rs b/tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs similarity index 100% rename from tests/rustdoc/ice-intra-doc-links-107995.rs rename to tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs diff --git a/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs b/tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs similarity index 100% rename from tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs rename to tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs From eee6c9753588fe1888d3ddb264f9516e7ac56997 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:34:16 +0200 Subject: [PATCH 160/262] Created `tests/rustdoc/private` subfolder to limit number of files at the top level --- tests/rustdoc/{ => private}/doc-hidden-private-67851-both.rs | 0 tests/rustdoc/{ => private}/doc-hidden-private-67851-hidden.rs | 0 tests/rustdoc/{ => private}/doc-hidden-private-67851-neither.rs | 0 tests/rustdoc/{ => private}/doc-hidden-private-67851-private.rs | 0 tests/rustdoc/{ => private}/empty-impl-block-private-with-doc.rs | 0 tests/rustdoc/{ => private}/empty-impl-block-private.rs | 0 tests/rustdoc/{ => private}/empty-mod-private.rs | 0 tests/rustdoc/{ => private}/enum-variant-private-46767.rs | 0 tests/rustdoc/{ => private}/files-creation-private.rs | 0 tests/rustdoc/{ => private}/hidden-private.rs | 0 .../{ => private}/inline-private-with-intermediate-doc-hidden.rs | 0 tests/rustdoc/{ => private}/inner-private-110422.rs | 0 tests/rustdoc/{ => private}/macro-document-private-duplicate.rs | 0 tests/rustdoc/{ => private}/macro-document-private.rs | 0 tests/rustdoc/{ => private}/macro-private-not-documented.rs | 0 tests/rustdoc/{ => private}/missing-private-inlining-109258.rs | 0 tests/rustdoc/{ => private}/private-fields-tuple-struct.rs | 0 tests/rustdoc/{ => private}/private-non-local-fields-2.rs | 0 tests/rustdoc/{ => private}/private-non-local-fields.rs | 0 tests/rustdoc/{ => private}/private-type-alias.rs | 0 tests/rustdoc/{ => private}/private-type-cycle-110629.rs | 0 tests/rustdoc/{ => private}/private-use-decl-macro-47038.rs | 0 tests/rustdoc/{ => private}/private-use.rs | 0 .../{ => private}/public-impl-mention-private-generic-46380-2.rs | 0 tests/rustdoc/{ => private}/traits-in-bodies-private.rs | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => private}/doc-hidden-private-67851-both.rs (100%) rename tests/rustdoc/{ => private}/doc-hidden-private-67851-hidden.rs (100%) rename tests/rustdoc/{ => private}/doc-hidden-private-67851-neither.rs (100%) rename tests/rustdoc/{ => private}/doc-hidden-private-67851-private.rs (100%) rename tests/rustdoc/{ => private}/empty-impl-block-private-with-doc.rs (100%) rename tests/rustdoc/{ => private}/empty-impl-block-private.rs (100%) rename tests/rustdoc/{ => private}/empty-mod-private.rs (100%) rename tests/rustdoc/{ => private}/enum-variant-private-46767.rs (100%) rename tests/rustdoc/{ => private}/files-creation-private.rs (100%) rename tests/rustdoc/{ => private}/hidden-private.rs (100%) rename tests/rustdoc/{ => private}/inline-private-with-intermediate-doc-hidden.rs (100%) rename tests/rustdoc/{ => private}/inner-private-110422.rs (100%) rename tests/rustdoc/{ => private}/macro-document-private-duplicate.rs (100%) rename tests/rustdoc/{ => private}/macro-document-private.rs (100%) rename tests/rustdoc/{ => private}/macro-private-not-documented.rs (100%) rename tests/rustdoc/{ => private}/missing-private-inlining-109258.rs (100%) rename tests/rustdoc/{ => private}/private-fields-tuple-struct.rs (100%) rename tests/rustdoc/{ => private}/private-non-local-fields-2.rs (100%) rename tests/rustdoc/{ => private}/private-non-local-fields.rs (100%) rename tests/rustdoc/{ => private}/private-type-alias.rs (100%) rename tests/rustdoc/{ => private}/private-type-cycle-110629.rs (100%) rename tests/rustdoc/{ => private}/private-use-decl-macro-47038.rs (100%) rename tests/rustdoc/{ => private}/private-use.rs (100%) rename tests/rustdoc/{ => private}/public-impl-mention-private-generic-46380-2.rs (100%) rename tests/rustdoc/{ => private}/traits-in-bodies-private.rs (100%) diff --git a/tests/rustdoc/doc-hidden-private-67851-both.rs b/tests/rustdoc/private/doc-hidden-private-67851-both.rs similarity index 100% rename from tests/rustdoc/doc-hidden-private-67851-both.rs rename to tests/rustdoc/private/doc-hidden-private-67851-both.rs diff --git a/tests/rustdoc/doc-hidden-private-67851-hidden.rs b/tests/rustdoc/private/doc-hidden-private-67851-hidden.rs similarity index 100% rename from tests/rustdoc/doc-hidden-private-67851-hidden.rs rename to tests/rustdoc/private/doc-hidden-private-67851-hidden.rs diff --git a/tests/rustdoc/doc-hidden-private-67851-neither.rs b/tests/rustdoc/private/doc-hidden-private-67851-neither.rs similarity index 100% rename from tests/rustdoc/doc-hidden-private-67851-neither.rs rename to tests/rustdoc/private/doc-hidden-private-67851-neither.rs diff --git a/tests/rustdoc/doc-hidden-private-67851-private.rs b/tests/rustdoc/private/doc-hidden-private-67851-private.rs similarity index 100% rename from tests/rustdoc/doc-hidden-private-67851-private.rs rename to tests/rustdoc/private/doc-hidden-private-67851-private.rs diff --git a/tests/rustdoc/empty-impl-block-private-with-doc.rs b/tests/rustdoc/private/empty-impl-block-private-with-doc.rs similarity index 100% rename from tests/rustdoc/empty-impl-block-private-with-doc.rs rename to tests/rustdoc/private/empty-impl-block-private-with-doc.rs diff --git a/tests/rustdoc/empty-impl-block-private.rs b/tests/rustdoc/private/empty-impl-block-private.rs similarity index 100% rename from tests/rustdoc/empty-impl-block-private.rs rename to tests/rustdoc/private/empty-impl-block-private.rs diff --git a/tests/rustdoc/empty-mod-private.rs b/tests/rustdoc/private/empty-mod-private.rs similarity index 100% rename from tests/rustdoc/empty-mod-private.rs rename to tests/rustdoc/private/empty-mod-private.rs diff --git a/tests/rustdoc/enum-variant-private-46767.rs b/tests/rustdoc/private/enum-variant-private-46767.rs similarity index 100% rename from tests/rustdoc/enum-variant-private-46767.rs rename to tests/rustdoc/private/enum-variant-private-46767.rs diff --git a/tests/rustdoc/files-creation-private.rs b/tests/rustdoc/private/files-creation-private.rs similarity index 100% rename from tests/rustdoc/files-creation-private.rs rename to tests/rustdoc/private/files-creation-private.rs diff --git a/tests/rustdoc/hidden-private.rs b/tests/rustdoc/private/hidden-private.rs similarity index 100% rename from tests/rustdoc/hidden-private.rs rename to tests/rustdoc/private/hidden-private.rs diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs similarity index 100% rename from tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs rename to tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs diff --git a/tests/rustdoc/inner-private-110422.rs b/tests/rustdoc/private/inner-private-110422.rs similarity index 100% rename from tests/rustdoc/inner-private-110422.rs rename to tests/rustdoc/private/inner-private-110422.rs diff --git a/tests/rustdoc/macro-document-private-duplicate.rs b/tests/rustdoc/private/macro-document-private-duplicate.rs similarity index 100% rename from tests/rustdoc/macro-document-private-duplicate.rs rename to tests/rustdoc/private/macro-document-private-duplicate.rs diff --git a/tests/rustdoc/macro-document-private.rs b/tests/rustdoc/private/macro-document-private.rs similarity index 100% rename from tests/rustdoc/macro-document-private.rs rename to tests/rustdoc/private/macro-document-private.rs diff --git a/tests/rustdoc/macro-private-not-documented.rs b/tests/rustdoc/private/macro-private-not-documented.rs similarity index 100% rename from tests/rustdoc/macro-private-not-documented.rs rename to tests/rustdoc/private/macro-private-not-documented.rs diff --git a/tests/rustdoc/missing-private-inlining-109258.rs b/tests/rustdoc/private/missing-private-inlining-109258.rs similarity index 100% rename from tests/rustdoc/missing-private-inlining-109258.rs rename to tests/rustdoc/private/missing-private-inlining-109258.rs diff --git a/tests/rustdoc/private-fields-tuple-struct.rs b/tests/rustdoc/private/private-fields-tuple-struct.rs similarity index 100% rename from tests/rustdoc/private-fields-tuple-struct.rs rename to tests/rustdoc/private/private-fields-tuple-struct.rs diff --git a/tests/rustdoc/private-non-local-fields-2.rs b/tests/rustdoc/private/private-non-local-fields-2.rs similarity index 100% rename from tests/rustdoc/private-non-local-fields-2.rs rename to tests/rustdoc/private/private-non-local-fields-2.rs diff --git a/tests/rustdoc/private-non-local-fields.rs b/tests/rustdoc/private/private-non-local-fields.rs similarity index 100% rename from tests/rustdoc/private-non-local-fields.rs rename to tests/rustdoc/private/private-non-local-fields.rs diff --git a/tests/rustdoc/private-type-alias.rs b/tests/rustdoc/private/private-type-alias.rs similarity index 100% rename from tests/rustdoc/private-type-alias.rs rename to tests/rustdoc/private/private-type-alias.rs diff --git a/tests/rustdoc/private-type-cycle-110629.rs b/tests/rustdoc/private/private-type-cycle-110629.rs similarity index 100% rename from tests/rustdoc/private-type-cycle-110629.rs rename to tests/rustdoc/private/private-type-cycle-110629.rs diff --git a/tests/rustdoc/private-use-decl-macro-47038.rs b/tests/rustdoc/private/private-use-decl-macro-47038.rs similarity index 100% rename from tests/rustdoc/private-use-decl-macro-47038.rs rename to tests/rustdoc/private/private-use-decl-macro-47038.rs diff --git a/tests/rustdoc/private-use.rs b/tests/rustdoc/private/private-use.rs similarity index 100% rename from tests/rustdoc/private-use.rs rename to tests/rustdoc/private/private-use.rs diff --git a/tests/rustdoc/public-impl-mention-private-generic-46380-2.rs b/tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs similarity index 100% rename from tests/rustdoc/public-impl-mention-private-generic-46380-2.rs rename to tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs diff --git a/tests/rustdoc/traits-in-bodies-private.rs b/tests/rustdoc/private/traits-in-bodies-private.rs similarity index 100% rename from tests/rustdoc/traits-in-bodies-private.rs rename to tests/rustdoc/private/traits-in-bodies-private.rs From d1f4a0bcb60ab868c496ca72a28b48ac0a4128af Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:40:02 +0200 Subject: [PATCH 161/262] Created `tests/rustdoc/macro` subfolder to limit number of files at the top level --- .../auxiliary/external-macro-src.rs | 0 .../macro/auxiliary/issue-99221-aux.rs | 20 +++++++++++++++++++ .../auxiliary/macro_pub_in_module.rs | 0 .../auxiliary/pub-use-extern-macros.rs | 0 .../{ => macro}/compiler-derive-proc-macro.rs | 0 .../const-rendering-macros-33302.rs | 0 tests/rustdoc/{ => macro}/decl_macro.rs | 0 tests/rustdoc/{ => macro}/decl_macro_priv.rs | 0 tests/rustdoc/{ => macro}/doc-proc-macro.rs | 0 .../rustdoc/{ => macro}/external-macro-src.rs | 0 .../{ => macro}/macro-const-display-115295.rs | 0 .../{ => macro}/macro-doc-comment-23812.rs | 0 .../macro-export-crate-root-108231.rs | 0 ...o-generated-macro.macro_linebreak_pre.html | 0 ...o-generated-macro.macro_morestuff_pre.html | 0 .../{ => macro}/macro-generated-macro.rs | 0 .../macro-higher-kinded-function.rs | 0 tests/rustdoc/{ => macro}/macro-ice-16019.rs | 0 .../{ => macro}/macro-in-async-block.rs | 0 tests/rustdoc/{ => macro}/macro-in-closure.rs | 0 .../rustdoc/{ => macro}/macro-indirect-use.rs | 0 .../{ => macro}/macro_pub_in_module.rs | 0 .../{ => macro}/macro_rules-matchers.rs | 0 tests/rustdoc/{ => macro}/macros.rs | 0 .../multiple-macro-rules-w-same-name-99221.rs | 0 ...macro-rules-w-same-name-submodule-99221.rs | 0 tests/rustdoc/{ => macro}/proc-macro.rs | 0 .../{ => macro}/pub-use-extern-macros.rs | 0 .../rustdoc/{ => macro}/rustc-macro-crate.rs | 0 29 files changed, 20 insertions(+) rename tests/rustdoc/{ => macro}/auxiliary/external-macro-src.rs (100%) create mode 100644 tests/rustdoc/macro/auxiliary/issue-99221-aux.rs rename tests/rustdoc/{ => macro}/auxiliary/macro_pub_in_module.rs (100%) rename tests/rustdoc/{ => macro}/auxiliary/pub-use-extern-macros.rs (100%) rename tests/rustdoc/{ => macro}/compiler-derive-proc-macro.rs (100%) rename tests/rustdoc/{ => macro}/const-rendering-macros-33302.rs (100%) rename tests/rustdoc/{ => macro}/decl_macro.rs (100%) rename tests/rustdoc/{ => macro}/decl_macro_priv.rs (100%) rename tests/rustdoc/{ => macro}/doc-proc-macro.rs (100%) rename tests/rustdoc/{ => macro}/external-macro-src.rs (100%) rename tests/rustdoc/{ => macro}/macro-const-display-115295.rs (100%) rename tests/rustdoc/{ => macro}/macro-doc-comment-23812.rs (100%) rename tests/rustdoc/{ => macro}/macro-export-crate-root-108231.rs (100%) rename tests/rustdoc/{ => macro}/macro-generated-macro.macro_linebreak_pre.html (100%) rename tests/rustdoc/{ => macro}/macro-generated-macro.macro_morestuff_pre.html (100%) rename tests/rustdoc/{ => macro}/macro-generated-macro.rs (100%) rename tests/rustdoc/{ => macro}/macro-higher-kinded-function.rs (100%) rename tests/rustdoc/{ => macro}/macro-ice-16019.rs (100%) rename tests/rustdoc/{ => macro}/macro-in-async-block.rs (100%) rename tests/rustdoc/{ => macro}/macro-in-closure.rs (100%) rename tests/rustdoc/{ => macro}/macro-indirect-use.rs (100%) rename tests/rustdoc/{ => macro}/macro_pub_in_module.rs (100%) rename tests/rustdoc/{ => macro}/macro_rules-matchers.rs (100%) rename tests/rustdoc/{ => macro}/macros.rs (100%) rename tests/rustdoc/{ => macro}/multiple-macro-rules-w-same-name-99221.rs (100%) rename tests/rustdoc/{ => macro}/multiple-macro-rules-w-same-name-submodule-99221.rs (100%) rename tests/rustdoc/{ => macro}/proc-macro.rs (100%) rename tests/rustdoc/{ => macro}/pub-use-extern-macros.rs (100%) rename tests/rustdoc/{ => macro}/rustc-macro-crate.rs (100%) diff --git a/tests/rustdoc/auxiliary/external-macro-src.rs b/tests/rustdoc/macro/auxiliary/external-macro-src.rs similarity index 100% rename from tests/rustdoc/auxiliary/external-macro-src.rs rename to tests/rustdoc/macro/auxiliary/external-macro-src.rs diff --git a/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs b/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs new file mode 100644 index 000000000000..e061e42b29db --- /dev/null +++ b/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs @@ -0,0 +1,20 @@ +pub struct Option; +impl Option { + pub fn unwrap(self) {} +} + +mod macros { + use crate::Option; + /// [`Option::unwrap`] + #[macro_export] + macro_rules! print { + () => () + } +} + +mod structs { + use crate::Option; + /// [`Option::unwrap`] + pub struct Print; +} +pub use structs::Print; diff --git a/tests/rustdoc/auxiliary/macro_pub_in_module.rs b/tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs similarity index 100% rename from tests/rustdoc/auxiliary/macro_pub_in_module.rs rename to tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs diff --git a/tests/rustdoc/auxiliary/pub-use-extern-macros.rs b/tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/auxiliary/pub-use-extern-macros.rs rename to tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs diff --git a/tests/rustdoc/compiler-derive-proc-macro.rs b/tests/rustdoc/macro/compiler-derive-proc-macro.rs similarity index 100% rename from tests/rustdoc/compiler-derive-proc-macro.rs rename to tests/rustdoc/macro/compiler-derive-proc-macro.rs diff --git a/tests/rustdoc/const-rendering-macros-33302.rs b/tests/rustdoc/macro/const-rendering-macros-33302.rs similarity index 100% rename from tests/rustdoc/const-rendering-macros-33302.rs rename to tests/rustdoc/macro/const-rendering-macros-33302.rs diff --git a/tests/rustdoc/decl_macro.rs b/tests/rustdoc/macro/decl_macro.rs similarity index 100% rename from tests/rustdoc/decl_macro.rs rename to tests/rustdoc/macro/decl_macro.rs diff --git a/tests/rustdoc/decl_macro_priv.rs b/tests/rustdoc/macro/decl_macro_priv.rs similarity index 100% rename from tests/rustdoc/decl_macro_priv.rs rename to tests/rustdoc/macro/decl_macro_priv.rs diff --git a/tests/rustdoc/doc-proc-macro.rs b/tests/rustdoc/macro/doc-proc-macro.rs similarity index 100% rename from tests/rustdoc/doc-proc-macro.rs rename to tests/rustdoc/macro/doc-proc-macro.rs diff --git a/tests/rustdoc/external-macro-src.rs b/tests/rustdoc/macro/external-macro-src.rs similarity index 100% rename from tests/rustdoc/external-macro-src.rs rename to tests/rustdoc/macro/external-macro-src.rs diff --git a/tests/rustdoc/macro-const-display-115295.rs b/tests/rustdoc/macro/macro-const-display-115295.rs similarity index 100% rename from tests/rustdoc/macro-const-display-115295.rs rename to tests/rustdoc/macro/macro-const-display-115295.rs diff --git a/tests/rustdoc/macro-doc-comment-23812.rs b/tests/rustdoc/macro/macro-doc-comment-23812.rs similarity index 100% rename from tests/rustdoc/macro-doc-comment-23812.rs rename to tests/rustdoc/macro/macro-doc-comment-23812.rs diff --git a/tests/rustdoc/macro-export-crate-root-108231.rs b/tests/rustdoc/macro/macro-export-crate-root-108231.rs similarity index 100% rename from tests/rustdoc/macro-export-crate-root-108231.rs rename to tests/rustdoc/macro/macro-export-crate-root-108231.rs diff --git a/tests/rustdoc/macro-generated-macro.macro_linebreak_pre.html b/tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html similarity index 100% rename from tests/rustdoc/macro-generated-macro.macro_linebreak_pre.html rename to tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html diff --git a/tests/rustdoc/macro-generated-macro.macro_morestuff_pre.html b/tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html similarity index 100% rename from tests/rustdoc/macro-generated-macro.macro_morestuff_pre.html rename to tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html diff --git a/tests/rustdoc/macro-generated-macro.rs b/tests/rustdoc/macro/macro-generated-macro.rs similarity index 100% rename from tests/rustdoc/macro-generated-macro.rs rename to tests/rustdoc/macro/macro-generated-macro.rs diff --git a/tests/rustdoc/macro-higher-kinded-function.rs b/tests/rustdoc/macro/macro-higher-kinded-function.rs similarity index 100% rename from tests/rustdoc/macro-higher-kinded-function.rs rename to tests/rustdoc/macro/macro-higher-kinded-function.rs diff --git a/tests/rustdoc/macro-ice-16019.rs b/tests/rustdoc/macro/macro-ice-16019.rs similarity index 100% rename from tests/rustdoc/macro-ice-16019.rs rename to tests/rustdoc/macro/macro-ice-16019.rs diff --git a/tests/rustdoc/macro-in-async-block.rs b/tests/rustdoc/macro/macro-in-async-block.rs similarity index 100% rename from tests/rustdoc/macro-in-async-block.rs rename to tests/rustdoc/macro/macro-in-async-block.rs diff --git a/tests/rustdoc/macro-in-closure.rs b/tests/rustdoc/macro/macro-in-closure.rs similarity index 100% rename from tests/rustdoc/macro-in-closure.rs rename to tests/rustdoc/macro/macro-in-closure.rs diff --git a/tests/rustdoc/macro-indirect-use.rs b/tests/rustdoc/macro/macro-indirect-use.rs similarity index 100% rename from tests/rustdoc/macro-indirect-use.rs rename to tests/rustdoc/macro/macro-indirect-use.rs diff --git a/tests/rustdoc/macro_pub_in_module.rs b/tests/rustdoc/macro/macro_pub_in_module.rs similarity index 100% rename from tests/rustdoc/macro_pub_in_module.rs rename to tests/rustdoc/macro/macro_pub_in_module.rs diff --git a/tests/rustdoc/macro_rules-matchers.rs b/tests/rustdoc/macro/macro_rules-matchers.rs similarity index 100% rename from tests/rustdoc/macro_rules-matchers.rs rename to tests/rustdoc/macro/macro_rules-matchers.rs diff --git a/tests/rustdoc/macros.rs b/tests/rustdoc/macro/macros.rs similarity index 100% rename from tests/rustdoc/macros.rs rename to tests/rustdoc/macro/macros.rs diff --git a/tests/rustdoc/multiple-macro-rules-w-same-name-99221.rs b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs similarity index 100% rename from tests/rustdoc/multiple-macro-rules-w-same-name-99221.rs rename to tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs diff --git a/tests/rustdoc/multiple-macro-rules-w-same-name-submodule-99221.rs b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs similarity index 100% rename from tests/rustdoc/multiple-macro-rules-w-same-name-submodule-99221.rs rename to tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs diff --git a/tests/rustdoc/proc-macro.rs b/tests/rustdoc/macro/proc-macro.rs similarity index 100% rename from tests/rustdoc/proc-macro.rs rename to tests/rustdoc/macro/proc-macro.rs diff --git a/tests/rustdoc/pub-use-extern-macros.rs b/tests/rustdoc/macro/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/pub-use-extern-macros.rs rename to tests/rustdoc/macro/pub-use-extern-macros.rs diff --git a/tests/rustdoc/rustc-macro-crate.rs b/tests/rustdoc/macro/rustc-macro-crate.rs similarity index 100% rename from tests/rustdoc/rustc-macro-crate.rs rename to tests/rustdoc/macro/rustc-macro-crate.rs From be71d8b24f1aebe9c45279d95a76db8fa6a62574 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 16:42:18 +0200 Subject: [PATCH 162/262] Created `tests/rustdoc/doc-cfg` subfolder to limit number of files at the top level --- tests/rustdoc/{ => doc-cfg}/doc-cfg-hide.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-implicit-gate.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-implicit.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-inherit-from-module-79201.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-simplification.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-target-feature.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg-traits.rs | 0 tests/rustdoc/{ => doc-cfg}/doc-cfg.rs | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-hide.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-implicit-gate.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-implicit.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-inherit-from-module-79201.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-simplification.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-target-feature.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg-traits.rs (100%) rename tests/rustdoc/{ => doc-cfg}/doc-cfg.rs (100%) diff --git a/tests/rustdoc/doc-cfg-hide.rs b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs similarity index 100% rename from tests/rustdoc/doc-cfg-hide.rs rename to tests/rustdoc/doc-cfg/doc-cfg-hide.rs diff --git a/tests/rustdoc/doc-cfg-implicit-gate.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs similarity index 100% rename from tests/rustdoc/doc-cfg-implicit-gate.rs rename to tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs diff --git a/tests/rustdoc/doc-cfg-implicit.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs similarity index 100% rename from tests/rustdoc/doc-cfg-implicit.rs rename to tests/rustdoc/doc-cfg/doc-cfg-implicit.rs diff --git a/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs b/tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs similarity index 100% rename from tests/rustdoc/doc-cfg-inherit-from-module-79201.rs rename to tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs diff --git a/tests/rustdoc/doc-cfg-simplification.rs b/tests/rustdoc/doc-cfg/doc-cfg-simplification.rs similarity index 100% rename from tests/rustdoc/doc-cfg-simplification.rs rename to tests/rustdoc/doc-cfg/doc-cfg-simplification.rs diff --git a/tests/rustdoc/doc-cfg-target-feature.rs b/tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs similarity index 100% rename from tests/rustdoc/doc-cfg-target-feature.rs rename to tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs diff --git a/tests/rustdoc/doc-cfg-traits.rs b/tests/rustdoc/doc-cfg/doc-cfg-traits.rs similarity index 100% rename from tests/rustdoc/doc-cfg-traits.rs rename to tests/rustdoc/doc-cfg/doc-cfg-traits.rs diff --git a/tests/rustdoc/doc-cfg.rs b/tests/rustdoc/doc-cfg/doc-cfg.rs similarity index 100% rename from tests/rustdoc/doc-cfg.rs rename to tests/rustdoc/doc-cfg/doc-cfg.rs From b84f4cc39e99f801dcd37125dffa67eb796c85b8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:01:08 +0200 Subject: [PATCH 163/262] Created `tests/rustdoc/impl` subfolder to limit number of files at the top level --- tests/rustdoc/{ => constant}/assoc-consts-underscore.rs | 0 tests/rustdoc/{ => constant}/assoc-consts-version.rs | 0 tests/rustdoc/{ => constant}/assoc-consts.rs | 0 tests/rustdoc/{ => constant}/associated-consts.rs | 0 tests/rustdoc/{ => constant}/const-display.rs | 0 tests/rustdoc/{ => constant}/const-doc.rs | 0 tests/rustdoc/{ => constant}/const-effect-param.rs | 0 tests/rustdoc/{ => constant}/const-underscore.rs | 0 tests/rustdoc/{ => constant}/const-value-display.rs | 0 tests/rustdoc/{ => constant}/const.rs | 0 .../document-item-with-associated-const-in-where-clause.rs | 0 tests/rustdoc/{ => constant}/generic-const-items.rs | 0 tests/rustdoc/{ => constant}/generic_const_exprs.rs | 0 tests/rustdoc/{ => constant}/glob-shadowing-const.rs | 0 .../{ => constant}/hide-complex-unevaluated-const-arguments.rs | 0 tests/rustdoc/{ => constant}/hide-complex-unevaluated-consts.rs | 0 .../{ => constant}/ice-associated-const-equality-105952.rs | 0 tests/rustdoc/{ => constant}/legacy-const-generic.rs | 0 tests/rustdoc/{ => constant}/link-assoc-const.rs | 0 tests/rustdoc/{ => constant}/redirect-const.rs | 0 tests/rustdoc/{ => constant}/rfc-2632-const-trait-impl.rs | 0 tests/rustdoc/{ => constant}/show-const-contents.rs | 0 .../{ => impl}/auxiliary/cross-crate-hidden-impl-parameter.rs | 0 tests/rustdoc/{ => impl}/auxiliary/extern-impl-trait.rs | 0 tests/rustdoc/{ => impl}/auxiliary/incoherent-impl-types.rs | 0 tests/rustdoc/{ => impl}/auxiliary/issue-100204-aux.rs | 0 tests/rustdoc/{ => impl}/auxiliary/issue-17476.rs | 0 tests/rustdoc/{ => impl}/auxiliary/issue-21092.rs | 0 tests/rustdoc/{ => impl}/auxiliary/issue-22025.rs | 0 tests/rustdoc/{ => impl}/auxiliary/issue-53689.rs | 0 tests/rustdoc/{ => impl}/auxiliary/precise-capturing.rs | 0 tests/rustdoc/{ => impl}/auxiliary/real_gimli.rs | 0 tests/rustdoc/{ => impl}/auxiliary/realcore.rs | 0 tests/rustdoc/{ => impl}/auxiliary/rustdoc-default-impl.rs | 0 .../rustdoc/{ => impl}/auxiliary/rustdoc-impl-parts-crosscrate.rs | 0 tests/rustdoc/{ => impl}/blanket-impl-29503.rs | 0 tests/rustdoc/{ => impl}/blanket-impl-78673.rs | 0 tests/rustdoc/{ => impl}/cross-crate-hidden-impl-parameter.rs | 0 tests/rustdoc/{ => impl}/deduplicate-glob-import-impl-21474.rs | 0 tests/rustdoc/{ => impl}/deduplicate-trait-impl-22025.rs | 0 tests/rustdoc/{ => impl}/default-impl.rs | 0 tests/rustdoc/{ => impl}/deprecated-impls.rs | 0 tests/rustdoc/{ => impl}/doc-hidden-trait-implementors-33069.rs | 0 tests/rustdoc/{ => impl}/doc_auto_cfg_nested_impl.rs | 0 tests/rustdoc/{ => impl}/duplicated_impl.rs | 0 tests/rustdoc/{ => impl}/empty-impl-block.rs | 0 tests/rustdoc/{ => impl}/empty-impls.rs | 0 tests/rustdoc/{ => impl}/extern-impl-trait.rs | 0 tests/rustdoc/{ => impl}/extern-impl.rs | 0 tests/rustdoc/{ => impl}/foreign-implementors-js-43701.rs | 0 tests/rustdoc/{ => impl}/generic-impl.rs | 0 tests/rustdoc/{ => impl}/hidden-implementors-90781.rs | 0 tests/rustdoc/{ => impl}/hidden-impls.rs | 0 tests/rustdoc/{ => impl}/hidden-trait-struct-impls.rs | 0 .../{ => impl}/hide-mut-methods-if-no-derefmut-impl-74083.rs | 0 tests/rustdoc/{ => impl}/impl-alias-substituted.rs | 0 tests/rustdoc/{ => impl}/impl-assoc-type-21092.rs | 0 tests/rustdoc/{ => impl}/impl-associated-items-order.rs | 0 tests/rustdoc/{ => impl}/impl-associated-items-sidebar.rs | 0 tests/rustdoc/{ => impl}/impl-blanket-53689.rs | 0 tests/rustdoc/{ => impl}/impl-box.rs | 0 tests/rustdoc/{ => impl}/impl-disambiguation.rs | 0 tests/rustdoc/{ => impl}/impl-everywhere.rs | 0 tests/rustdoc/{ => impl}/impl-in-const-block.rs | 0 tests/rustdoc/{ => impl}/impl-on-ty-alias-issue-119015.rs | 0 tests/rustdoc/{ => impl}/impl-parts-crosscrate.rs | 0 tests/rustdoc/{ => impl}/impl-parts.rs | 0 tests/rustdoc/{ => impl}/impl-ref-20175.rs | 0 tests/rustdoc/{ => impl}/impl-trait-43869.rs | 0 tests/rustdoc/{ => impl}/impl-trait-alias.rs | 0 tests/rustdoc/{ => impl}/impl-trait-precise-capturing.rs | 0 tests/rustdoc/{ => impl}/impl-type-parameter-33592.rs | 0 tests/rustdoc/{ => impl}/implementor-stable-version.rs | 0 tests/rustdoc/{ => impl}/implementors-unstable-75588.rs | 0 .../rustdoc/{ => impl}/inline-impl-through-glob-import-100204.rs | 0 tests/rustdoc/{ => impl}/manual_impl.rs | 0 tests/rustdoc/{ => impl}/method-link-foreign-trait-impl-17476.rs | 0 tests/rustdoc/{ => impl}/module-impls.rs | 0 tests/rustdoc/{ => impl}/must_implement_one_of.rs | 0 tests/rustdoc/{ => impl}/negative-impl-no-items.rs | 0 tests/rustdoc/{ => impl}/negative-impl-sidebar.rs | 0 tests/rustdoc/{ => impl}/negative-impl.rs | 0 tests/rustdoc/{ => impl}/return-impl-trait.rs | 0 tests/rustdoc/{ => impl}/rustc-incoherent-impls.rs | 0 tests/rustdoc/{ => impl}/same-crate-hidden-impl-parameter.rs | 0 tests/rustdoc/{ => impl}/sidebar-trait-impl-disambiguate-78701.rs | 0 tests/rustdoc/{ => impl}/struct-implementations-title.rs | 0 tests/rustdoc/{ => impl}/trait-impl.rs | 0 .../{ => impl}/trait-implementations-duplicate-self-45584.rs | 0 tests/rustdoc/{ => impl}/underscore-type-in-trait-impl-96381.rs | 0 tests/rustdoc/{ => impl}/universal-impl-trait.rs | 0 tests/rustdoc/{ => impl}/unneeded-trait-implementations-title.rs | 0 92 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => constant}/assoc-consts-underscore.rs (100%) rename tests/rustdoc/{ => constant}/assoc-consts-version.rs (100%) rename tests/rustdoc/{ => constant}/assoc-consts.rs (100%) rename tests/rustdoc/{ => constant}/associated-consts.rs (100%) rename tests/rustdoc/{ => constant}/const-display.rs (100%) rename tests/rustdoc/{ => constant}/const-doc.rs (100%) rename tests/rustdoc/{ => constant}/const-effect-param.rs (100%) rename tests/rustdoc/{ => constant}/const-underscore.rs (100%) rename tests/rustdoc/{ => constant}/const-value-display.rs (100%) rename tests/rustdoc/{ => constant}/const.rs (100%) rename tests/rustdoc/{ => constant}/document-item-with-associated-const-in-where-clause.rs (100%) rename tests/rustdoc/{ => constant}/generic-const-items.rs (100%) rename tests/rustdoc/{ => constant}/generic_const_exprs.rs (100%) rename tests/rustdoc/{ => constant}/glob-shadowing-const.rs (100%) rename tests/rustdoc/{ => constant}/hide-complex-unevaluated-const-arguments.rs (100%) rename tests/rustdoc/{ => constant}/hide-complex-unevaluated-consts.rs (100%) rename tests/rustdoc/{ => constant}/ice-associated-const-equality-105952.rs (100%) rename tests/rustdoc/{ => constant}/legacy-const-generic.rs (100%) rename tests/rustdoc/{ => constant}/link-assoc-const.rs (100%) rename tests/rustdoc/{ => constant}/redirect-const.rs (100%) rename tests/rustdoc/{ => constant}/rfc-2632-const-trait-impl.rs (100%) rename tests/rustdoc/{ => constant}/show-const-contents.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/cross-crate-hidden-impl-parameter.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/extern-impl-trait.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/incoherent-impl-types.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/issue-100204-aux.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/issue-17476.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/issue-21092.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/issue-22025.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/issue-53689.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/precise-capturing.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/real_gimli.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/realcore.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/rustdoc-default-impl.rs (100%) rename tests/rustdoc/{ => impl}/auxiliary/rustdoc-impl-parts-crosscrate.rs (100%) rename tests/rustdoc/{ => impl}/blanket-impl-29503.rs (100%) rename tests/rustdoc/{ => impl}/blanket-impl-78673.rs (100%) rename tests/rustdoc/{ => impl}/cross-crate-hidden-impl-parameter.rs (100%) rename tests/rustdoc/{ => impl}/deduplicate-glob-import-impl-21474.rs (100%) rename tests/rustdoc/{ => impl}/deduplicate-trait-impl-22025.rs (100%) rename tests/rustdoc/{ => impl}/default-impl.rs (100%) rename tests/rustdoc/{ => impl}/deprecated-impls.rs (100%) rename tests/rustdoc/{ => impl}/doc-hidden-trait-implementors-33069.rs (100%) rename tests/rustdoc/{ => impl}/doc_auto_cfg_nested_impl.rs (100%) rename tests/rustdoc/{ => impl}/duplicated_impl.rs (100%) rename tests/rustdoc/{ => impl}/empty-impl-block.rs (100%) rename tests/rustdoc/{ => impl}/empty-impls.rs (100%) rename tests/rustdoc/{ => impl}/extern-impl-trait.rs (100%) rename tests/rustdoc/{ => impl}/extern-impl.rs (100%) rename tests/rustdoc/{ => impl}/foreign-implementors-js-43701.rs (100%) rename tests/rustdoc/{ => impl}/generic-impl.rs (100%) rename tests/rustdoc/{ => impl}/hidden-implementors-90781.rs (100%) rename tests/rustdoc/{ => impl}/hidden-impls.rs (100%) rename tests/rustdoc/{ => impl}/hidden-trait-struct-impls.rs (100%) rename tests/rustdoc/{ => impl}/hide-mut-methods-if-no-derefmut-impl-74083.rs (100%) rename tests/rustdoc/{ => impl}/impl-alias-substituted.rs (100%) rename tests/rustdoc/{ => impl}/impl-assoc-type-21092.rs (100%) rename tests/rustdoc/{ => impl}/impl-associated-items-order.rs (100%) rename tests/rustdoc/{ => impl}/impl-associated-items-sidebar.rs (100%) rename tests/rustdoc/{ => impl}/impl-blanket-53689.rs (100%) rename tests/rustdoc/{ => impl}/impl-box.rs (100%) rename tests/rustdoc/{ => impl}/impl-disambiguation.rs (100%) rename tests/rustdoc/{ => impl}/impl-everywhere.rs (100%) rename tests/rustdoc/{ => impl}/impl-in-const-block.rs (100%) rename tests/rustdoc/{ => impl}/impl-on-ty-alias-issue-119015.rs (100%) rename tests/rustdoc/{ => impl}/impl-parts-crosscrate.rs (100%) rename tests/rustdoc/{ => impl}/impl-parts.rs (100%) rename tests/rustdoc/{ => impl}/impl-ref-20175.rs (100%) rename tests/rustdoc/{ => impl}/impl-trait-43869.rs (100%) rename tests/rustdoc/{ => impl}/impl-trait-alias.rs (100%) rename tests/rustdoc/{ => impl}/impl-trait-precise-capturing.rs (100%) rename tests/rustdoc/{ => impl}/impl-type-parameter-33592.rs (100%) rename tests/rustdoc/{ => impl}/implementor-stable-version.rs (100%) rename tests/rustdoc/{ => impl}/implementors-unstable-75588.rs (100%) rename tests/rustdoc/{ => impl}/inline-impl-through-glob-import-100204.rs (100%) rename tests/rustdoc/{ => impl}/manual_impl.rs (100%) rename tests/rustdoc/{ => impl}/method-link-foreign-trait-impl-17476.rs (100%) rename tests/rustdoc/{ => impl}/module-impls.rs (100%) rename tests/rustdoc/{ => impl}/must_implement_one_of.rs (100%) rename tests/rustdoc/{ => impl}/negative-impl-no-items.rs (100%) rename tests/rustdoc/{ => impl}/negative-impl-sidebar.rs (100%) rename tests/rustdoc/{ => impl}/negative-impl.rs (100%) rename tests/rustdoc/{ => impl}/return-impl-trait.rs (100%) rename tests/rustdoc/{ => impl}/rustc-incoherent-impls.rs (100%) rename tests/rustdoc/{ => impl}/same-crate-hidden-impl-parameter.rs (100%) rename tests/rustdoc/{ => impl}/sidebar-trait-impl-disambiguate-78701.rs (100%) rename tests/rustdoc/{ => impl}/struct-implementations-title.rs (100%) rename tests/rustdoc/{ => impl}/trait-impl.rs (100%) rename tests/rustdoc/{ => impl}/trait-implementations-duplicate-self-45584.rs (100%) rename tests/rustdoc/{ => impl}/underscore-type-in-trait-impl-96381.rs (100%) rename tests/rustdoc/{ => impl}/universal-impl-trait.rs (100%) rename tests/rustdoc/{ => impl}/unneeded-trait-implementations-title.rs (100%) diff --git a/tests/rustdoc/assoc-consts-underscore.rs b/tests/rustdoc/constant/assoc-consts-underscore.rs similarity index 100% rename from tests/rustdoc/assoc-consts-underscore.rs rename to tests/rustdoc/constant/assoc-consts-underscore.rs diff --git a/tests/rustdoc/assoc-consts-version.rs b/tests/rustdoc/constant/assoc-consts-version.rs similarity index 100% rename from tests/rustdoc/assoc-consts-version.rs rename to tests/rustdoc/constant/assoc-consts-version.rs diff --git a/tests/rustdoc/assoc-consts.rs b/tests/rustdoc/constant/assoc-consts.rs similarity index 100% rename from tests/rustdoc/assoc-consts.rs rename to tests/rustdoc/constant/assoc-consts.rs diff --git a/tests/rustdoc/associated-consts.rs b/tests/rustdoc/constant/associated-consts.rs similarity index 100% rename from tests/rustdoc/associated-consts.rs rename to tests/rustdoc/constant/associated-consts.rs diff --git a/tests/rustdoc/const-display.rs b/tests/rustdoc/constant/const-display.rs similarity index 100% rename from tests/rustdoc/const-display.rs rename to tests/rustdoc/constant/const-display.rs diff --git a/tests/rustdoc/const-doc.rs b/tests/rustdoc/constant/const-doc.rs similarity index 100% rename from tests/rustdoc/const-doc.rs rename to tests/rustdoc/constant/const-doc.rs diff --git a/tests/rustdoc/const-effect-param.rs b/tests/rustdoc/constant/const-effect-param.rs similarity index 100% rename from tests/rustdoc/const-effect-param.rs rename to tests/rustdoc/constant/const-effect-param.rs diff --git a/tests/rustdoc/const-underscore.rs b/tests/rustdoc/constant/const-underscore.rs similarity index 100% rename from tests/rustdoc/const-underscore.rs rename to tests/rustdoc/constant/const-underscore.rs diff --git a/tests/rustdoc/const-value-display.rs b/tests/rustdoc/constant/const-value-display.rs similarity index 100% rename from tests/rustdoc/const-value-display.rs rename to tests/rustdoc/constant/const-value-display.rs diff --git a/tests/rustdoc/const.rs b/tests/rustdoc/constant/const.rs similarity index 100% rename from tests/rustdoc/const.rs rename to tests/rustdoc/constant/const.rs diff --git a/tests/rustdoc/document-item-with-associated-const-in-where-clause.rs b/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs similarity index 100% rename from tests/rustdoc/document-item-with-associated-const-in-where-clause.rs rename to tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs diff --git a/tests/rustdoc/generic-const-items.rs b/tests/rustdoc/constant/generic-const-items.rs similarity index 100% rename from tests/rustdoc/generic-const-items.rs rename to tests/rustdoc/constant/generic-const-items.rs diff --git a/tests/rustdoc/generic_const_exprs.rs b/tests/rustdoc/constant/generic_const_exprs.rs similarity index 100% rename from tests/rustdoc/generic_const_exprs.rs rename to tests/rustdoc/constant/generic_const_exprs.rs diff --git a/tests/rustdoc/glob-shadowing-const.rs b/tests/rustdoc/constant/glob-shadowing-const.rs similarity index 100% rename from tests/rustdoc/glob-shadowing-const.rs rename to tests/rustdoc/constant/glob-shadowing-const.rs diff --git a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs similarity index 100% rename from tests/rustdoc/hide-complex-unevaluated-const-arguments.rs rename to tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs diff --git a/tests/rustdoc/hide-complex-unevaluated-consts.rs b/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs similarity index 100% rename from tests/rustdoc/hide-complex-unevaluated-consts.rs rename to tests/rustdoc/constant/hide-complex-unevaluated-consts.rs diff --git a/tests/rustdoc/ice-associated-const-equality-105952.rs b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs similarity index 100% rename from tests/rustdoc/ice-associated-const-equality-105952.rs rename to tests/rustdoc/constant/ice-associated-const-equality-105952.rs diff --git a/tests/rustdoc/legacy-const-generic.rs b/tests/rustdoc/constant/legacy-const-generic.rs similarity index 100% rename from tests/rustdoc/legacy-const-generic.rs rename to tests/rustdoc/constant/legacy-const-generic.rs diff --git a/tests/rustdoc/link-assoc-const.rs b/tests/rustdoc/constant/link-assoc-const.rs similarity index 100% rename from tests/rustdoc/link-assoc-const.rs rename to tests/rustdoc/constant/link-assoc-const.rs diff --git a/tests/rustdoc/redirect-const.rs b/tests/rustdoc/constant/redirect-const.rs similarity index 100% rename from tests/rustdoc/redirect-const.rs rename to tests/rustdoc/constant/redirect-const.rs diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs similarity index 100% rename from tests/rustdoc/rfc-2632-const-trait-impl.rs rename to tests/rustdoc/constant/rfc-2632-const-trait-impl.rs diff --git a/tests/rustdoc/show-const-contents.rs b/tests/rustdoc/constant/show-const-contents.rs similarity index 100% rename from tests/rustdoc/show-const-contents.rs rename to tests/rustdoc/constant/show-const-contents.rs diff --git a/tests/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/auxiliary/extern-impl-trait.rs b/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/auxiliary/extern-impl-trait.rs rename to tests/rustdoc/impl/auxiliary/extern-impl-trait.rs diff --git a/tests/rustdoc/auxiliary/incoherent-impl-types.rs b/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs similarity index 100% rename from tests/rustdoc/auxiliary/incoherent-impl-types.rs rename to tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs diff --git a/tests/rustdoc/auxiliary/issue-100204-aux.rs b/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-100204-aux.rs rename to tests/rustdoc/impl/auxiliary/issue-100204-aux.rs diff --git a/tests/rustdoc/auxiliary/issue-17476.rs b/tests/rustdoc/impl/auxiliary/issue-17476.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-17476.rs rename to tests/rustdoc/impl/auxiliary/issue-17476.rs diff --git a/tests/rustdoc/auxiliary/issue-21092.rs b/tests/rustdoc/impl/auxiliary/issue-21092.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-21092.rs rename to tests/rustdoc/impl/auxiliary/issue-21092.rs diff --git a/tests/rustdoc/auxiliary/issue-22025.rs b/tests/rustdoc/impl/auxiliary/issue-22025.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-22025.rs rename to tests/rustdoc/impl/auxiliary/issue-22025.rs diff --git a/tests/rustdoc/auxiliary/issue-53689.rs b/tests/rustdoc/impl/auxiliary/issue-53689.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-53689.rs rename to tests/rustdoc/impl/auxiliary/issue-53689.rs diff --git a/tests/rustdoc/auxiliary/precise-capturing.rs b/tests/rustdoc/impl/auxiliary/precise-capturing.rs similarity index 100% rename from tests/rustdoc/auxiliary/precise-capturing.rs rename to tests/rustdoc/impl/auxiliary/precise-capturing.rs diff --git a/tests/rustdoc/auxiliary/real_gimli.rs b/tests/rustdoc/impl/auxiliary/real_gimli.rs similarity index 100% rename from tests/rustdoc/auxiliary/real_gimli.rs rename to tests/rustdoc/impl/auxiliary/real_gimli.rs diff --git a/tests/rustdoc/auxiliary/realcore.rs b/tests/rustdoc/impl/auxiliary/realcore.rs similarity index 100% rename from tests/rustdoc/auxiliary/realcore.rs rename to tests/rustdoc/impl/auxiliary/realcore.rs diff --git a/tests/rustdoc/auxiliary/rustdoc-default-impl.rs b/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-default-impl.rs rename to tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs diff --git a/tests/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs b/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs rename to tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs diff --git a/tests/rustdoc/blanket-impl-29503.rs b/tests/rustdoc/impl/blanket-impl-29503.rs similarity index 100% rename from tests/rustdoc/blanket-impl-29503.rs rename to tests/rustdoc/impl/blanket-impl-29503.rs diff --git a/tests/rustdoc/blanket-impl-78673.rs b/tests/rustdoc/impl/blanket-impl-78673.rs similarity index 100% rename from tests/rustdoc/blanket-impl-78673.rs rename to tests/rustdoc/impl/blanket-impl-78673.rs diff --git a/tests/rustdoc/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/deduplicate-glob-import-impl-21474.rs b/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs similarity index 100% rename from tests/rustdoc/deduplicate-glob-import-impl-21474.rs rename to tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs diff --git a/tests/rustdoc/deduplicate-trait-impl-22025.rs b/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs similarity index 100% rename from tests/rustdoc/deduplicate-trait-impl-22025.rs rename to tests/rustdoc/impl/deduplicate-trait-impl-22025.rs diff --git a/tests/rustdoc/default-impl.rs b/tests/rustdoc/impl/default-impl.rs similarity index 100% rename from tests/rustdoc/default-impl.rs rename to tests/rustdoc/impl/default-impl.rs diff --git a/tests/rustdoc/deprecated-impls.rs b/tests/rustdoc/impl/deprecated-impls.rs similarity index 100% rename from tests/rustdoc/deprecated-impls.rs rename to tests/rustdoc/impl/deprecated-impls.rs diff --git a/tests/rustdoc/doc-hidden-trait-implementors-33069.rs b/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs similarity index 100% rename from tests/rustdoc/doc-hidden-trait-implementors-33069.rs rename to tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs diff --git a/tests/rustdoc/doc_auto_cfg_nested_impl.rs b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg_nested_impl.rs rename to tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs diff --git a/tests/rustdoc/duplicated_impl.rs b/tests/rustdoc/impl/duplicated_impl.rs similarity index 100% rename from tests/rustdoc/duplicated_impl.rs rename to tests/rustdoc/impl/duplicated_impl.rs diff --git a/tests/rustdoc/empty-impl-block.rs b/tests/rustdoc/impl/empty-impl-block.rs similarity index 100% rename from tests/rustdoc/empty-impl-block.rs rename to tests/rustdoc/impl/empty-impl-block.rs diff --git a/tests/rustdoc/empty-impls.rs b/tests/rustdoc/impl/empty-impls.rs similarity index 100% rename from tests/rustdoc/empty-impls.rs rename to tests/rustdoc/impl/empty-impls.rs diff --git a/tests/rustdoc/extern-impl-trait.rs b/tests/rustdoc/impl/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/extern-impl-trait.rs rename to tests/rustdoc/impl/extern-impl-trait.rs diff --git a/tests/rustdoc/extern-impl.rs b/tests/rustdoc/impl/extern-impl.rs similarity index 100% rename from tests/rustdoc/extern-impl.rs rename to tests/rustdoc/impl/extern-impl.rs diff --git a/tests/rustdoc/foreign-implementors-js-43701.rs b/tests/rustdoc/impl/foreign-implementors-js-43701.rs similarity index 100% rename from tests/rustdoc/foreign-implementors-js-43701.rs rename to tests/rustdoc/impl/foreign-implementors-js-43701.rs diff --git a/tests/rustdoc/generic-impl.rs b/tests/rustdoc/impl/generic-impl.rs similarity index 100% rename from tests/rustdoc/generic-impl.rs rename to tests/rustdoc/impl/generic-impl.rs diff --git a/tests/rustdoc/hidden-implementors-90781.rs b/tests/rustdoc/impl/hidden-implementors-90781.rs similarity index 100% rename from tests/rustdoc/hidden-implementors-90781.rs rename to tests/rustdoc/impl/hidden-implementors-90781.rs diff --git a/tests/rustdoc/hidden-impls.rs b/tests/rustdoc/impl/hidden-impls.rs similarity index 100% rename from tests/rustdoc/hidden-impls.rs rename to tests/rustdoc/impl/hidden-impls.rs diff --git a/tests/rustdoc/hidden-trait-struct-impls.rs b/tests/rustdoc/impl/hidden-trait-struct-impls.rs similarity index 100% rename from tests/rustdoc/hidden-trait-struct-impls.rs rename to tests/rustdoc/impl/hidden-trait-struct-impls.rs diff --git a/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs b/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs similarity index 100% rename from tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs rename to tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs diff --git a/tests/rustdoc/impl-alias-substituted.rs b/tests/rustdoc/impl/impl-alias-substituted.rs similarity index 100% rename from tests/rustdoc/impl-alias-substituted.rs rename to tests/rustdoc/impl/impl-alias-substituted.rs diff --git a/tests/rustdoc/impl-assoc-type-21092.rs b/tests/rustdoc/impl/impl-assoc-type-21092.rs similarity index 100% rename from tests/rustdoc/impl-assoc-type-21092.rs rename to tests/rustdoc/impl/impl-assoc-type-21092.rs diff --git a/tests/rustdoc/impl-associated-items-order.rs b/tests/rustdoc/impl/impl-associated-items-order.rs similarity index 100% rename from tests/rustdoc/impl-associated-items-order.rs rename to tests/rustdoc/impl/impl-associated-items-order.rs diff --git a/tests/rustdoc/impl-associated-items-sidebar.rs b/tests/rustdoc/impl/impl-associated-items-sidebar.rs similarity index 100% rename from tests/rustdoc/impl-associated-items-sidebar.rs rename to tests/rustdoc/impl/impl-associated-items-sidebar.rs diff --git a/tests/rustdoc/impl-blanket-53689.rs b/tests/rustdoc/impl/impl-blanket-53689.rs similarity index 100% rename from tests/rustdoc/impl-blanket-53689.rs rename to tests/rustdoc/impl/impl-blanket-53689.rs diff --git a/tests/rustdoc/impl-box.rs b/tests/rustdoc/impl/impl-box.rs similarity index 100% rename from tests/rustdoc/impl-box.rs rename to tests/rustdoc/impl/impl-box.rs diff --git a/tests/rustdoc/impl-disambiguation.rs b/tests/rustdoc/impl/impl-disambiguation.rs similarity index 100% rename from tests/rustdoc/impl-disambiguation.rs rename to tests/rustdoc/impl/impl-disambiguation.rs diff --git a/tests/rustdoc/impl-everywhere.rs b/tests/rustdoc/impl/impl-everywhere.rs similarity index 100% rename from tests/rustdoc/impl-everywhere.rs rename to tests/rustdoc/impl/impl-everywhere.rs diff --git a/tests/rustdoc/impl-in-const-block.rs b/tests/rustdoc/impl/impl-in-const-block.rs similarity index 100% rename from tests/rustdoc/impl-in-const-block.rs rename to tests/rustdoc/impl/impl-in-const-block.rs diff --git a/tests/rustdoc/impl-on-ty-alias-issue-119015.rs b/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs similarity index 100% rename from tests/rustdoc/impl-on-ty-alias-issue-119015.rs rename to tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl/impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/impl-parts-crosscrate.rs rename to tests/rustdoc/impl/impl-parts-crosscrate.rs diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl/impl-parts.rs similarity index 100% rename from tests/rustdoc/impl-parts.rs rename to tests/rustdoc/impl/impl-parts.rs diff --git a/tests/rustdoc/impl-ref-20175.rs b/tests/rustdoc/impl/impl-ref-20175.rs similarity index 100% rename from tests/rustdoc/impl-ref-20175.rs rename to tests/rustdoc/impl/impl-ref-20175.rs diff --git a/tests/rustdoc/impl-trait-43869.rs b/tests/rustdoc/impl/impl-trait-43869.rs similarity index 100% rename from tests/rustdoc/impl-trait-43869.rs rename to tests/rustdoc/impl/impl-trait-43869.rs diff --git a/tests/rustdoc/impl-trait-alias.rs b/tests/rustdoc/impl/impl-trait-alias.rs similarity index 100% rename from tests/rustdoc/impl-trait-alias.rs rename to tests/rustdoc/impl/impl-trait-alias.rs diff --git a/tests/rustdoc/impl-trait-precise-capturing.rs b/tests/rustdoc/impl/impl-trait-precise-capturing.rs similarity index 100% rename from tests/rustdoc/impl-trait-precise-capturing.rs rename to tests/rustdoc/impl/impl-trait-precise-capturing.rs diff --git a/tests/rustdoc/impl-type-parameter-33592.rs b/tests/rustdoc/impl/impl-type-parameter-33592.rs similarity index 100% rename from tests/rustdoc/impl-type-parameter-33592.rs rename to tests/rustdoc/impl/impl-type-parameter-33592.rs diff --git a/tests/rustdoc/implementor-stable-version.rs b/tests/rustdoc/impl/implementor-stable-version.rs similarity index 100% rename from tests/rustdoc/implementor-stable-version.rs rename to tests/rustdoc/impl/implementor-stable-version.rs diff --git a/tests/rustdoc/implementors-unstable-75588.rs b/tests/rustdoc/impl/implementors-unstable-75588.rs similarity index 100% rename from tests/rustdoc/implementors-unstable-75588.rs rename to tests/rustdoc/impl/implementors-unstable-75588.rs diff --git a/tests/rustdoc/inline-impl-through-glob-import-100204.rs b/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs similarity index 100% rename from tests/rustdoc/inline-impl-through-glob-import-100204.rs rename to tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs diff --git a/tests/rustdoc/manual_impl.rs b/tests/rustdoc/impl/manual_impl.rs similarity index 100% rename from tests/rustdoc/manual_impl.rs rename to tests/rustdoc/impl/manual_impl.rs diff --git a/tests/rustdoc/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs similarity index 100% rename from tests/rustdoc/method-link-foreign-trait-impl-17476.rs rename to tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs diff --git a/tests/rustdoc/module-impls.rs b/tests/rustdoc/impl/module-impls.rs similarity index 100% rename from tests/rustdoc/module-impls.rs rename to tests/rustdoc/impl/module-impls.rs diff --git a/tests/rustdoc/must_implement_one_of.rs b/tests/rustdoc/impl/must_implement_one_of.rs similarity index 100% rename from tests/rustdoc/must_implement_one_of.rs rename to tests/rustdoc/impl/must_implement_one_of.rs diff --git a/tests/rustdoc/negative-impl-no-items.rs b/tests/rustdoc/impl/negative-impl-no-items.rs similarity index 100% rename from tests/rustdoc/negative-impl-no-items.rs rename to tests/rustdoc/impl/negative-impl-no-items.rs diff --git a/tests/rustdoc/negative-impl-sidebar.rs b/tests/rustdoc/impl/negative-impl-sidebar.rs similarity index 100% rename from tests/rustdoc/negative-impl-sidebar.rs rename to tests/rustdoc/impl/negative-impl-sidebar.rs diff --git a/tests/rustdoc/negative-impl.rs b/tests/rustdoc/impl/negative-impl.rs similarity index 100% rename from tests/rustdoc/negative-impl.rs rename to tests/rustdoc/impl/negative-impl.rs diff --git a/tests/rustdoc/return-impl-trait.rs b/tests/rustdoc/impl/return-impl-trait.rs similarity index 100% rename from tests/rustdoc/return-impl-trait.rs rename to tests/rustdoc/impl/return-impl-trait.rs diff --git a/tests/rustdoc/rustc-incoherent-impls.rs b/tests/rustdoc/impl/rustc-incoherent-impls.rs similarity index 100% rename from tests/rustdoc/rustc-incoherent-impls.rs rename to tests/rustdoc/impl/rustc-incoherent-impls.rs diff --git a/tests/rustdoc/same-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/same-crate-hidden-impl-parameter.rs rename to tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs b/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs similarity index 100% rename from tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs rename to tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs diff --git a/tests/rustdoc/struct-implementations-title.rs b/tests/rustdoc/impl/struct-implementations-title.rs similarity index 100% rename from tests/rustdoc/struct-implementations-title.rs rename to tests/rustdoc/impl/struct-implementations-title.rs diff --git a/tests/rustdoc/trait-impl.rs b/tests/rustdoc/impl/trait-impl.rs similarity index 100% rename from tests/rustdoc/trait-impl.rs rename to tests/rustdoc/impl/trait-impl.rs diff --git a/tests/rustdoc/trait-implementations-duplicate-self-45584.rs b/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs similarity index 100% rename from tests/rustdoc/trait-implementations-duplicate-self-45584.rs rename to tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs diff --git a/tests/rustdoc/underscore-type-in-trait-impl-96381.rs b/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs similarity index 100% rename from tests/rustdoc/underscore-type-in-trait-impl-96381.rs rename to tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs diff --git a/tests/rustdoc/universal-impl-trait.rs b/tests/rustdoc/impl/universal-impl-trait.rs similarity index 100% rename from tests/rustdoc/universal-impl-trait.rs rename to tests/rustdoc/impl/universal-impl-trait.rs diff --git a/tests/rustdoc/unneeded-trait-implementations-title.rs b/tests/rustdoc/impl/unneeded-trait-implementations-title.rs similarity index 100% rename from tests/rustdoc/unneeded-trait-implementations-title.rs rename to tests/rustdoc/impl/unneeded-trait-implementations-title.rs From fa2b9227a1065f7618eb90b52f6f617a13c55b30 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:08:06 +0200 Subject: [PATCH 164/262] Created `tests/rustdoc/assoc` subfolder to limit number of files at the top level --- tests/rustdoc/{ => assoc}/assoc-fns.rs | 0 tests/rustdoc/{ => assoc}/assoc-item-cast.rs | 0 tests/rustdoc/{ => assoc}/assoc-type-bindings-20646.rs | 0 tests/rustdoc/{ => assoc}/assoc-types.rs | 0 .../{ => assoc}/auxiliary/cross-crate-hidden-assoc-trait-items.rs | 0 tests/rustdoc/{ => assoc}/auxiliary/issue-20646.rs | 0 tests/rustdoc/{ => assoc}/auxiliary/issue-20727.rs | 0 tests/rustdoc/{ => assoc}/auxiliary/normalize-assoc-item.rs | 0 tests/rustdoc/{ => assoc}/cross-crate-hidden-assoc-trait-items.rs | 0 tests/rustdoc/{ => assoc}/doc-assoc-item.rs | 0 tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bindings.rs | 0 tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds-deref.rs | 0 tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds-index.rs | 0 tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds.rs | 0 tests/rustdoc/{ => assoc}/normalize-assoc-item.rs | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => assoc}/assoc-fns.rs (100%) rename tests/rustdoc/{ => assoc}/assoc-item-cast.rs (100%) rename tests/rustdoc/{ => assoc}/assoc-type-bindings-20646.rs (100%) rename tests/rustdoc/{ => assoc}/assoc-types.rs (100%) rename tests/rustdoc/{ => assoc}/auxiliary/cross-crate-hidden-assoc-trait-items.rs (100%) rename tests/rustdoc/{ => assoc}/auxiliary/issue-20646.rs (100%) rename tests/rustdoc/{ => assoc}/auxiliary/issue-20727.rs (100%) rename tests/rustdoc/{ => assoc}/auxiliary/normalize-assoc-item.rs (100%) rename tests/rustdoc/{ => assoc}/cross-crate-hidden-assoc-trait-items.rs (100%) rename tests/rustdoc/{ => assoc}/doc-assoc-item.rs (100%) rename tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bindings.rs (100%) rename tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds-deref.rs (100%) rename tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds-index.rs (100%) rename tests/rustdoc/{ => assoc}/inline-assoc-type-20727-bounds.rs (100%) rename tests/rustdoc/{ => assoc}/normalize-assoc-item.rs (100%) diff --git a/tests/rustdoc/assoc-fns.rs b/tests/rustdoc/assoc/assoc-fns.rs similarity index 100% rename from tests/rustdoc/assoc-fns.rs rename to tests/rustdoc/assoc/assoc-fns.rs diff --git a/tests/rustdoc/assoc-item-cast.rs b/tests/rustdoc/assoc/assoc-item-cast.rs similarity index 100% rename from tests/rustdoc/assoc-item-cast.rs rename to tests/rustdoc/assoc/assoc-item-cast.rs diff --git a/tests/rustdoc/assoc-type-bindings-20646.rs b/tests/rustdoc/assoc/assoc-type-bindings-20646.rs similarity index 100% rename from tests/rustdoc/assoc-type-bindings-20646.rs rename to tests/rustdoc/assoc/assoc-type-bindings-20646.rs diff --git a/tests/rustdoc/assoc-types.rs b/tests/rustdoc/assoc/assoc-types.rs similarity index 100% rename from tests/rustdoc/assoc-types.rs rename to tests/rustdoc/assoc/assoc-types.rs diff --git a/tests/rustdoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/auxiliary/issue-20646.rs b/tests/rustdoc/assoc/auxiliary/issue-20646.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-20646.rs rename to tests/rustdoc/assoc/auxiliary/issue-20646.rs diff --git a/tests/rustdoc/auxiliary/issue-20727.rs b/tests/rustdoc/assoc/auxiliary/issue-20727.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-20727.rs rename to tests/rustdoc/assoc/auxiliary/issue-20727.rs diff --git a/tests/rustdoc/auxiliary/normalize-assoc-item.rs b/tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/auxiliary/normalize-assoc-item.rs rename to tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs diff --git a/tests/rustdoc/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/doc-assoc-item.rs b/tests/rustdoc/assoc/doc-assoc-item.rs similarity index 100% rename from tests/rustdoc/doc-assoc-item.rs rename to tests/rustdoc/assoc/doc-assoc-item.rs diff --git a/tests/rustdoc/inline-assoc-type-20727-bindings.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs similarity index 100% rename from tests/rustdoc/inline-assoc-type-20727-bindings.rs rename to tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs similarity index 100% rename from tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs rename to tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs similarity index 100% rename from tests/rustdoc/inline-assoc-type-20727-bounds-index.rs rename to tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs similarity index 100% rename from tests/rustdoc/inline-assoc-type-20727-bounds.rs rename to tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs diff --git a/tests/rustdoc/normalize-assoc-item.rs b/tests/rustdoc/assoc/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/normalize-assoc-item.rs rename to tests/rustdoc/assoc/normalize-assoc-item.rs From 4b6bc735079bc07928efe791fecc9ec6cba81fe1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:13:39 +0200 Subject: [PATCH 165/262] Created `tests/rustdoc/enum` subfolder to limit number of files at the top level --- tests/rustdoc/{ => enum}/auxiliary/enum-variant.rs | 0 tests/rustdoc/{ => enum}/auxiliary/variant-struct.rs | 0 tests/rustdoc/{ => enum}/enum-headings.rs | 0 tests/rustdoc/{ => enum}/enum-non-exhaustive-108925.rs | 0 tests/rustdoc/{ => enum}/enum-variant-doc-hidden-field-88600.rs | 0 tests/rustdoc/{ => enum}/enum-variant-fields-heading.rs | 0 .../rustdoc/{ => enum}/enum-variant-fields-heading.variants.html | 0 tests/rustdoc/{ => enum}/enum-variant-value.rs | 0 tests/rustdoc/{ => enum}/render-enum-variant-structlike-32395.rs | 0 tests/rustdoc/{ => enum}/strip-enum-variant.no-not-shown.html | 0 tests/rustdoc/{ => enum}/strip-enum-variant.rs | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => enum}/auxiliary/enum-variant.rs (100%) rename tests/rustdoc/{ => enum}/auxiliary/variant-struct.rs (100%) rename tests/rustdoc/{ => enum}/enum-headings.rs (100%) rename tests/rustdoc/{ => enum}/enum-non-exhaustive-108925.rs (100%) rename tests/rustdoc/{ => enum}/enum-variant-doc-hidden-field-88600.rs (100%) rename tests/rustdoc/{ => enum}/enum-variant-fields-heading.rs (100%) rename tests/rustdoc/{ => enum}/enum-variant-fields-heading.variants.html (100%) rename tests/rustdoc/{ => enum}/enum-variant-value.rs (100%) rename tests/rustdoc/{ => enum}/render-enum-variant-structlike-32395.rs (100%) rename tests/rustdoc/{ => enum}/strip-enum-variant.no-not-shown.html (100%) rename tests/rustdoc/{ => enum}/strip-enum-variant.rs (100%) diff --git a/tests/rustdoc/auxiliary/enum-variant.rs b/tests/rustdoc/enum/auxiliary/enum-variant.rs similarity index 100% rename from tests/rustdoc/auxiliary/enum-variant.rs rename to tests/rustdoc/enum/auxiliary/enum-variant.rs diff --git a/tests/rustdoc/auxiliary/variant-struct.rs b/tests/rustdoc/enum/auxiliary/variant-struct.rs similarity index 100% rename from tests/rustdoc/auxiliary/variant-struct.rs rename to tests/rustdoc/enum/auxiliary/variant-struct.rs diff --git a/tests/rustdoc/enum-headings.rs b/tests/rustdoc/enum/enum-headings.rs similarity index 100% rename from tests/rustdoc/enum-headings.rs rename to tests/rustdoc/enum/enum-headings.rs diff --git a/tests/rustdoc/enum-non-exhaustive-108925.rs b/tests/rustdoc/enum/enum-non-exhaustive-108925.rs similarity index 100% rename from tests/rustdoc/enum-non-exhaustive-108925.rs rename to tests/rustdoc/enum/enum-non-exhaustive-108925.rs diff --git a/tests/rustdoc/enum-variant-doc-hidden-field-88600.rs b/tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs similarity index 100% rename from tests/rustdoc/enum-variant-doc-hidden-field-88600.rs rename to tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs diff --git a/tests/rustdoc/enum-variant-fields-heading.rs b/tests/rustdoc/enum/enum-variant-fields-heading.rs similarity index 100% rename from tests/rustdoc/enum-variant-fields-heading.rs rename to tests/rustdoc/enum/enum-variant-fields-heading.rs diff --git a/tests/rustdoc/enum-variant-fields-heading.variants.html b/tests/rustdoc/enum/enum-variant-fields-heading.variants.html similarity index 100% rename from tests/rustdoc/enum-variant-fields-heading.variants.html rename to tests/rustdoc/enum/enum-variant-fields-heading.variants.html diff --git a/tests/rustdoc/enum-variant-value.rs b/tests/rustdoc/enum/enum-variant-value.rs similarity index 100% rename from tests/rustdoc/enum-variant-value.rs rename to tests/rustdoc/enum/enum-variant-value.rs diff --git a/tests/rustdoc/render-enum-variant-structlike-32395.rs b/tests/rustdoc/enum/render-enum-variant-structlike-32395.rs similarity index 100% rename from tests/rustdoc/render-enum-variant-structlike-32395.rs rename to tests/rustdoc/enum/render-enum-variant-structlike-32395.rs diff --git a/tests/rustdoc/strip-enum-variant.no-not-shown.html b/tests/rustdoc/enum/strip-enum-variant.no-not-shown.html similarity index 100% rename from tests/rustdoc/strip-enum-variant.no-not-shown.html rename to tests/rustdoc/enum/strip-enum-variant.no-not-shown.html diff --git a/tests/rustdoc/strip-enum-variant.rs b/tests/rustdoc/enum/strip-enum-variant.rs similarity index 100% rename from tests/rustdoc/strip-enum-variant.rs rename to tests/rustdoc/enum/strip-enum-variant.rs From e245c3bc6bb7d278106649be9a03fc9b374e196b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:18:50 +0200 Subject: [PATCH 166/262] Move primitive rustdoc tests into the `primitive` sub folder --- tests/rustdoc/{ => primitive}/auxiliary/issue-15318.rs | 0 tests/rustdoc/{ => primitive}/auxiliary/primitive-doc.rs | 0 tests/rustdoc/{ => primitive}/cross-crate-primitive-doc.rs | 0 tests/rustdoc/{ => primitive}/no_std-primitive.rs | 0 tests/rustdoc/{ => primitive}/primitive-link.rs | 0 .../rustdoc/{ => primitive}/primitive-raw-pointer-dox-15318-3.rs | 0 tests/rustdoc/{ => primitive}/primitive-raw-pointer-link-15318.rs | 0 .../primitive-raw-pointer-link-no-inlined-15318-2.rs | 0 tests/rustdoc/{ => primitive}/primitive-reference.rs | 0 tests/rustdoc/{ => primitive}/primitive-slice-auto-trait.rs | 0 tests/rustdoc/{ => primitive}/primitive-tuple-auto-trait.rs | 0 tests/rustdoc/{ => primitive}/primitive-tuple-variadic.rs | 0 tests/rustdoc/{ => primitive}/primitive-unit-auto-trait.rs | 0 .../search-index-primitive-inherent-method-23511.rs | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => primitive}/auxiliary/issue-15318.rs (100%) rename tests/rustdoc/{ => primitive}/auxiliary/primitive-doc.rs (100%) rename tests/rustdoc/{ => primitive}/cross-crate-primitive-doc.rs (100%) rename tests/rustdoc/{ => primitive}/no_std-primitive.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-link.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-raw-pointer-dox-15318-3.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-raw-pointer-link-15318.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-raw-pointer-link-no-inlined-15318-2.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-reference.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-slice-auto-trait.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-tuple-auto-trait.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-tuple-variadic.rs (100%) rename tests/rustdoc/{ => primitive}/primitive-unit-auto-trait.rs (100%) rename tests/rustdoc/{ => primitive}/search-index-primitive-inherent-method-23511.rs (100%) diff --git a/tests/rustdoc/auxiliary/issue-15318.rs b/tests/rustdoc/primitive/auxiliary/issue-15318.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-15318.rs rename to tests/rustdoc/primitive/auxiliary/issue-15318.rs diff --git a/tests/rustdoc/auxiliary/primitive-doc.rs b/tests/rustdoc/primitive/auxiliary/primitive-doc.rs similarity index 100% rename from tests/rustdoc/auxiliary/primitive-doc.rs rename to tests/rustdoc/primitive/auxiliary/primitive-doc.rs diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/primitive/cross-crate-primitive-doc.rs similarity index 100% rename from tests/rustdoc/cross-crate-primitive-doc.rs rename to tests/rustdoc/primitive/cross-crate-primitive-doc.rs diff --git a/tests/rustdoc/no_std-primitive.rs b/tests/rustdoc/primitive/no_std-primitive.rs similarity index 100% rename from tests/rustdoc/no_std-primitive.rs rename to tests/rustdoc/primitive/no_std-primitive.rs diff --git a/tests/rustdoc/primitive-link.rs b/tests/rustdoc/primitive/primitive-link.rs similarity index 100% rename from tests/rustdoc/primitive-link.rs rename to tests/rustdoc/primitive/primitive-link.rs diff --git a/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs similarity index 100% rename from tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs rename to tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs diff --git a/tests/rustdoc/primitive-raw-pointer-link-15318.rs b/tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs similarity index 100% rename from tests/rustdoc/primitive-raw-pointer-link-15318.rs rename to tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs diff --git a/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs similarity index 100% rename from tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs rename to tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs diff --git a/tests/rustdoc/primitive-reference.rs b/tests/rustdoc/primitive/primitive-reference.rs similarity index 100% rename from tests/rustdoc/primitive-reference.rs rename to tests/rustdoc/primitive/primitive-reference.rs diff --git a/tests/rustdoc/primitive-slice-auto-trait.rs b/tests/rustdoc/primitive/primitive-slice-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive-slice-auto-trait.rs rename to tests/rustdoc/primitive/primitive-slice-auto-trait.rs diff --git a/tests/rustdoc/primitive-tuple-auto-trait.rs b/tests/rustdoc/primitive/primitive-tuple-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive-tuple-auto-trait.rs rename to tests/rustdoc/primitive/primitive-tuple-auto-trait.rs diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive/primitive-tuple-variadic.rs similarity index 100% rename from tests/rustdoc/primitive-tuple-variadic.rs rename to tests/rustdoc/primitive/primitive-tuple-variadic.rs diff --git a/tests/rustdoc/primitive-unit-auto-trait.rs b/tests/rustdoc/primitive/primitive-unit-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive-unit-auto-trait.rs rename to tests/rustdoc/primitive/primitive-unit-auto-trait.rs diff --git a/tests/rustdoc/search-index-primitive-inherent-method-23511.rs b/tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs similarity index 100% rename from tests/rustdoc/search-index-primitive-inherent-method-23511.rs rename to tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs From e14e19a67dcdd7437b29bd37b4aa1fde3e5fecee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:30:40 +0200 Subject: [PATCH 167/262] Created `tests/rustdoc/extern` subfolder to limit number of files at the top level --- tests/rustdoc/extern/auxiliary/empty.rs | 1 + tests/rustdoc/{ => extern}/auxiliary/extern-links.rs | 0 tests/rustdoc/{ => extern}/auxiliary/external-cross-doc.md | 0 tests/rustdoc/{ => extern}/auxiliary/external-cross.rs | 0 tests/rustdoc/{ => extern}/auxiliary/external-doc.md | 0 tests/rustdoc/{ => extern}/auxiliary/html_root.rs | 0 tests/rustdoc/{ => extern}/auxiliary/issue-30109-1.rs | 0 tests/rustdoc/{ => extern}/auxiliary/no_html_root.rs | 0 tests/rustdoc/{ => extern}/auxiliary/panic-item.rs | 0 tests/rustdoc/{ => extern}/auxiliary/pub-extern-crate.rs | 0 .../{ => extern}/auxiliary/rustdoc-extern-default-method.rs | 0 .../rustdoc/{ => extern}/auxiliary/rustdoc-extern-method.rs | 0 tests/rustdoc/extern/auxiliary/variant-struct.rs | 5 +++++ .../extern-default-method.no_href_on_anchor.html | 0 tests/rustdoc/{ => extern}/extern-default-method.rs | 0 tests/rustdoc/{ => extern}/extern-fn-22038.rs | 0 .../rustdoc/{ => extern}/extern-html-root-url-precedence.rs | 0 tests/rustdoc/{ => extern}/extern-html-root-url.rs | 0 tests/rustdoc/{ => extern}/extern-links.rs | 0 tests/rustdoc/{ => extern}/extern-method.rs | 0 tests/rustdoc/{ => extern}/external-cross.rs | 0 tests/rustdoc/{ => extern}/external-doc.rs | 0 tests/rustdoc/{ => extern}/hidden-extern-34025.rs | 0 tests/rustdoc/{ => extern}/link-extern-crate-33178.rs | 0 tests/rustdoc/{ => extern}/link-extern-crate-item-30109.rs | 0 tests/rustdoc/{ => extern}/link-extern-crate-title-33178.rs | 0 tests/rustdoc/{ => extern}/pub-extern-crate.rs | 0 tests/rustdoc/{ => extern}/unsafe-extern-blocks.rs | 0 tests/rustdoc/{ => extern}/unused-extern-crate.rs | 0 29 files changed, 6 insertions(+) create mode 100644 tests/rustdoc/extern/auxiliary/empty.rs rename tests/rustdoc/{ => extern}/auxiliary/extern-links.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/external-cross-doc.md (100%) rename tests/rustdoc/{ => extern}/auxiliary/external-cross.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/external-doc.md (100%) rename tests/rustdoc/{ => extern}/auxiliary/html_root.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/issue-30109-1.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/no_html_root.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/panic-item.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/pub-extern-crate.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/rustdoc-extern-default-method.rs (100%) rename tests/rustdoc/{ => extern}/auxiliary/rustdoc-extern-method.rs (100%) create mode 100644 tests/rustdoc/extern/auxiliary/variant-struct.rs rename tests/rustdoc/{anchors => extern}/extern-default-method.no_href_on_anchor.html (100%) rename tests/rustdoc/{ => extern}/extern-default-method.rs (100%) rename tests/rustdoc/{ => extern}/extern-fn-22038.rs (100%) rename tests/rustdoc/{ => extern}/extern-html-root-url-precedence.rs (100%) rename tests/rustdoc/{ => extern}/extern-html-root-url.rs (100%) rename tests/rustdoc/{ => extern}/extern-links.rs (100%) rename tests/rustdoc/{ => extern}/extern-method.rs (100%) rename tests/rustdoc/{ => extern}/external-cross.rs (100%) rename tests/rustdoc/{ => extern}/external-doc.rs (100%) rename tests/rustdoc/{ => extern}/hidden-extern-34025.rs (100%) rename tests/rustdoc/{ => extern}/link-extern-crate-33178.rs (100%) rename tests/rustdoc/{ => extern}/link-extern-crate-item-30109.rs (100%) rename tests/rustdoc/{ => extern}/link-extern-crate-title-33178.rs (100%) rename tests/rustdoc/{ => extern}/pub-extern-crate.rs (100%) rename tests/rustdoc/{ => extern}/unsafe-extern-blocks.rs (100%) rename tests/rustdoc/{ => extern}/unused-extern-crate.rs (100%) diff --git a/tests/rustdoc/extern/auxiliary/empty.rs b/tests/rustdoc/extern/auxiliary/empty.rs new file mode 100644 index 000000000000..d11c69f812a8 --- /dev/null +++ b/tests/rustdoc/extern/auxiliary/empty.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/tests/rustdoc/auxiliary/extern-links.rs b/tests/rustdoc/extern/auxiliary/extern-links.rs similarity index 100% rename from tests/rustdoc/auxiliary/extern-links.rs rename to tests/rustdoc/extern/auxiliary/extern-links.rs diff --git a/tests/rustdoc/auxiliary/external-cross-doc.md b/tests/rustdoc/extern/auxiliary/external-cross-doc.md similarity index 100% rename from tests/rustdoc/auxiliary/external-cross-doc.md rename to tests/rustdoc/extern/auxiliary/external-cross-doc.md diff --git a/tests/rustdoc/auxiliary/external-cross.rs b/tests/rustdoc/extern/auxiliary/external-cross.rs similarity index 100% rename from tests/rustdoc/auxiliary/external-cross.rs rename to tests/rustdoc/extern/auxiliary/external-cross.rs diff --git a/tests/rustdoc/auxiliary/external-doc.md b/tests/rustdoc/extern/auxiliary/external-doc.md similarity index 100% rename from tests/rustdoc/auxiliary/external-doc.md rename to tests/rustdoc/extern/auxiliary/external-doc.md diff --git a/tests/rustdoc/auxiliary/html_root.rs b/tests/rustdoc/extern/auxiliary/html_root.rs similarity index 100% rename from tests/rustdoc/auxiliary/html_root.rs rename to tests/rustdoc/extern/auxiliary/html_root.rs diff --git a/tests/rustdoc/auxiliary/issue-30109-1.rs b/tests/rustdoc/extern/auxiliary/issue-30109-1.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-30109-1.rs rename to tests/rustdoc/extern/auxiliary/issue-30109-1.rs diff --git a/tests/rustdoc/auxiliary/no_html_root.rs b/tests/rustdoc/extern/auxiliary/no_html_root.rs similarity index 100% rename from tests/rustdoc/auxiliary/no_html_root.rs rename to tests/rustdoc/extern/auxiliary/no_html_root.rs diff --git a/tests/rustdoc/auxiliary/panic-item.rs b/tests/rustdoc/extern/auxiliary/panic-item.rs similarity index 100% rename from tests/rustdoc/auxiliary/panic-item.rs rename to tests/rustdoc/extern/auxiliary/panic-item.rs diff --git a/tests/rustdoc/auxiliary/pub-extern-crate.rs b/tests/rustdoc/extern/auxiliary/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/auxiliary/pub-extern-crate.rs rename to tests/rustdoc/extern/auxiliary/pub-extern-crate.rs diff --git a/tests/rustdoc/auxiliary/rustdoc-extern-default-method.rs b/tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-extern-default-method.rs rename to tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs diff --git a/tests/rustdoc/auxiliary/rustdoc-extern-method.rs b/tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-extern-method.rs rename to tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs diff --git a/tests/rustdoc/extern/auxiliary/variant-struct.rs b/tests/rustdoc/extern/auxiliary/variant-struct.rs new file mode 100644 index 000000000000..0f3d2e5f1b7a --- /dev/null +++ b/tests/rustdoc/extern/auxiliary/variant-struct.rs @@ -0,0 +1,5 @@ +pub enum Foo { + Bar { + qux: (), + } +} diff --git a/tests/rustdoc/anchors/extern-default-method.no_href_on_anchor.html b/tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html similarity index 100% rename from tests/rustdoc/anchors/extern-default-method.no_href_on_anchor.html rename to tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html diff --git a/tests/rustdoc/extern-default-method.rs b/tests/rustdoc/extern/extern-default-method.rs similarity index 100% rename from tests/rustdoc/extern-default-method.rs rename to tests/rustdoc/extern/extern-default-method.rs diff --git a/tests/rustdoc/extern-fn-22038.rs b/tests/rustdoc/extern/extern-fn-22038.rs similarity index 100% rename from tests/rustdoc/extern-fn-22038.rs rename to tests/rustdoc/extern/extern-fn-22038.rs diff --git a/tests/rustdoc/extern-html-root-url-precedence.rs b/tests/rustdoc/extern/extern-html-root-url-precedence.rs similarity index 100% rename from tests/rustdoc/extern-html-root-url-precedence.rs rename to tests/rustdoc/extern/extern-html-root-url-precedence.rs diff --git a/tests/rustdoc/extern-html-root-url.rs b/tests/rustdoc/extern/extern-html-root-url.rs similarity index 100% rename from tests/rustdoc/extern-html-root-url.rs rename to tests/rustdoc/extern/extern-html-root-url.rs diff --git a/tests/rustdoc/extern-links.rs b/tests/rustdoc/extern/extern-links.rs similarity index 100% rename from tests/rustdoc/extern-links.rs rename to tests/rustdoc/extern/extern-links.rs diff --git a/tests/rustdoc/extern-method.rs b/tests/rustdoc/extern/extern-method.rs similarity index 100% rename from tests/rustdoc/extern-method.rs rename to tests/rustdoc/extern/extern-method.rs diff --git a/tests/rustdoc/external-cross.rs b/tests/rustdoc/extern/external-cross.rs similarity index 100% rename from tests/rustdoc/external-cross.rs rename to tests/rustdoc/extern/external-cross.rs diff --git a/tests/rustdoc/external-doc.rs b/tests/rustdoc/extern/external-doc.rs similarity index 100% rename from tests/rustdoc/external-doc.rs rename to tests/rustdoc/extern/external-doc.rs diff --git a/tests/rustdoc/hidden-extern-34025.rs b/tests/rustdoc/extern/hidden-extern-34025.rs similarity index 100% rename from tests/rustdoc/hidden-extern-34025.rs rename to tests/rustdoc/extern/hidden-extern-34025.rs diff --git a/tests/rustdoc/link-extern-crate-33178.rs b/tests/rustdoc/extern/link-extern-crate-33178.rs similarity index 100% rename from tests/rustdoc/link-extern-crate-33178.rs rename to tests/rustdoc/extern/link-extern-crate-33178.rs diff --git a/tests/rustdoc/link-extern-crate-item-30109.rs b/tests/rustdoc/extern/link-extern-crate-item-30109.rs similarity index 100% rename from tests/rustdoc/link-extern-crate-item-30109.rs rename to tests/rustdoc/extern/link-extern-crate-item-30109.rs diff --git a/tests/rustdoc/link-extern-crate-title-33178.rs b/tests/rustdoc/extern/link-extern-crate-title-33178.rs similarity index 100% rename from tests/rustdoc/link-extern-crate-title-33178.rs rename to tests/rustdoc/extern/link-extern-crate-title-33178.rs diff --git a/tests/rustdoc/pub-extern-crate.rs b/tests/rustdoc/extern/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/pub-extern-crate.rs rename to tests/rustdoc/extern/pub-extern-crate.rs diff --git a/tests/rustdoc/unsafe-extern-blocks.rs b/tests/rustdoc/extern/unsafe-extern-blocks.rs similarity index 100% rename from tests/rustdoc/unsafe-extern-blocks.rs rename to tests/rustdoc/extern/unsafe-extern-blocks.rs diff --git a/tests/rustdoc/unused-extern-crate.rs b/tests/rustdoc/extern/unused-extern-crate.rs similarity index 100% rename from tests/rustdoc/unused-extern-crate.rs rename to tests/rustdoc/extern/unused-extern-crate.rs From 27e39c3ac6173e4a9e9e1439bfc48f0ca1505542 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 5 May 2025 17:35:41 +0200 Subject: [PATCH 168/262] Created `tests/rustdoc/async` subfolder to limit number of files at the top level --- tests/rustdoc/{ => async}/async-fn-opaque-item.rs | 0 tests/rustdoc/{ => async}/async-fn.rs | 0 tests/rustdoc/{ => async}/async-move-doctest.rs | 0 tests/rustdoc/{ => async}/async-trait-sig.rs | 0 tests/rustdoc/{ => async}/async-trait.rs | 0 tests/rustdoc/{ => async}/auxiliary/async-trait-dep.rs | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => async}/async-fn-opaque-item.rs (100%) rename tests/rustdoc/{ => async}/async-fn.rs (100%) rename tests/rustdoc/{ => async}/async-move-doctest.rs (100%) rename tests/rustdoc/{ => async}/async-trait-sig.rs (100%) rename tests/rustdoc/{ => async}/async-trait.rs (100%) rename tests/rustdoc/{ => async}/auxiliary/async-trait-dep.rs (100%) diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async/async-fn-opaque-item.rs similarity index 100% rename from tests/rustdoc/async-fn-opaque-item.rs rename to tests/rustdoc/async/async-fn-opaque-item.rs diff --git a/tests/rustdoc/async-fn.rs b/tests/rustdoc/async/async-fn.rs similarity index 100% rename from tests/rustdoc/async-fn.rs rename to tests/rustdoc/async/async-fn.rs diff --git a/tests/rustdoc/async-move-doctest.rs b/tests/rustdoc/async/async-move-doctest.rs similarity index 100% rename from tests/rustdoc/async-move-doctest.rs rename to tests/rustdoc/async/async-move-doctest.rs diff --git a/tests/rustdoc/async-trait-sig.rs b/tests/rustdoc/async/async-trait-sig.rs similarity index 100% rename from tests/rustdoc/async-trait-sig.rs rename to tests/rustdoc/async/async-trait-sig.rs diff --git a/tests/rustdoc/async-trait.rs b/tests/rustdoc/async/async-trait.rs similarity index 100% rename from tests/rustdoc/async-trait.rs rename to tests/rustdoc/async/async-trait.rs diff --git a/tests/rustdoc/auxiliary/async-trait-dep.rs b/tests/rustdoc/async/auxiliary/async-trait-dep.rs similarity index 100% rename from tests/rustdoc/auxiliary/async-trait-dep.rs rename to tests/rustdoc/async/auxiliary/async-trait-dep.rs From 12d3021ef0e756490ed0adce13b66058cce75744 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 May 2025 15:47:50 +0000 Subject: [PATCH 169/262] Deeply normalize in the new solver in WF --- .../rustc_hir_analysis/src/check/wfcheck.rs | 47 +++++++++++++++---- .../bugs/wf-check-skipped.next.stderr | 13 ----- .../bugs/wf-check-skipped.rs | 5 +- .../inherent-impls-overflow.current.stderr | 8 ++-- .../inherent-impls-overflow.next.stderr | 46 ++++++++++++++++-- .../inherent-impls-overflow.rs | 8 +++- ...dont-ice-on-bad-transmute-in-typeck.stderr | 4 +- .../next-solver/issue-118950-root-region.rs | 1 + .../issue-118950-root-region.stderr | 14 +++++- .../non-wf-in-coerce-pointers.stderr | 4 +- .../ui/wf/check-wf-of-normalized-signature.rs | 24 ++++++++++ .../ui/wf/wf-normalization-sized.next.stderr | 25 +--------- tests/ui/wf/wf-normalization-sized.rs | 2 - 13 files changed, 137 insertions(+), 64 deletions(-) delete mode 100644 tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr create mode 100644 tests/ui/wf/check-wf-of-normalized-signature.rs diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index fa36fe797161..2ec14b2f018c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -76,6 +76,36 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { ) } + /// Convenience function to *deeply* normalize during wfcheck. In the old solver, + /// this just dispatches to [`WfCheckingCtxt::normalize`], but in the new solver + /// this calls `deeply_normalize` and reports errors if they are encountered. + /// + /// This function should be called in favor of `normalize` in cases where we will + /// then check the well-formedness of the type, since we only use the normalized + /// signature types for implied bounds when checking regions. + // FIXME(-Znext-solver): This should be removed when we compute implied outlives + // bounds using the unnormalized signature of the function we're checking. + fn deeply_normalize(&self, span: Span, loc: Option, value: T) -> T + where + T: TypeFoldable>, + { + if self.infcx.next_trait_solver() { + match self.ocx.deeply_normalize( + &ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)), + self.param_env, + value.clone(), + ) { + Ok(value) => value, + Err(errors) => { + self.infcx.err_ctxt().report_fulfillment_errors(errors); + value + } + } + } else { + self.normalize(span, loc, value) + } + } + fn register_wf_obligation(&self, span: Span, loc: Option, term: ty::Term<'tcx>) { let cause = traits::ObligationCause::new( span, @@ -297,7 +327,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() { let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { let ty = tcx.type_of(def_id).instantiate_identity(); - let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); + let item_ty = + wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation( hir_ty.span, Some(WellFormedLoc::Ty(def_id)), @@ -1073,7 +1104,7 @@ fn check_associated_item( match item.kind { ty::AssocKind::Const { .. } => { let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); check_sized_if_body( wfcx, @@ -1102,7 +1133,7 @@ fn check_associated_item( } if item.defaultness(tcx).has_value() { let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } Ok(()) @@ -1149,7 +1180,7 @@ fn check_type_defn<'tcx>( let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = tcx.hir_node_by_def_id(field_id).expect_field(); - let ty = wfcx.normalize( + let ty = wfcx.deeply_normalize( hir_ty.span, None, tcx.type_of(field.did).instantiate_identity(), @@ -1310,7 +1341,7 @@ fn check_item_type( enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| { let ty = tcx.type_of(item_id).instantiate_identity(); - let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty); + let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty); let forbid_unsized = match unsized_handling { UnsizedHandling::Forbid => true, @@ -1375,7 +1406,7 @@ fn check_impl<'tcx>( // other `Foo` impls are incoherent. tcx.ensure_ok().coherent_trait(trait_ref.def_id)?; let trait_span = hir_trait_ref.path.span; - let trait_ref = wfcx.normalize( + let trait_ref = wfcx.deeply_normalize( trait_span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), trait_ref, @@ -1435,7 +1466,7 @@ fn check_impl<'tcx>( } None => { let self_ty = tcx.type_of(item.owner_id).instantiate_identity(); - let self_ty = wfcx.normalize( + let self_ty = wfcx.deeply_normalize( item.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), self_ty, @@ -1640,7 +1671,7 @@ fn check_fn_or_method<'tcx>( sig.inputs_and_output = tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| { - wfcx.normalize( + wfcx.deeply_normalize( arg_span(idx), Some(WellFormedLoc::Param { function: def_id, diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr deleted file mode 100644 index 81ace4ebb6da..000000000000 --- a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0277]: the size for values of type `[u32]` cannot be known at compilation time - --> $DIR/wf-check-skipped.rs:17:25 - | -LL | fn main() -> Foo::Bar::> {} - | ^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u32]` -note: required by an implicit `Sized` bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs index 52df4efd13e9..2949007d770a 100644 --- a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs +++ b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs @@ -1,8 +1,8 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] known-bug: #100041 -//@[current] check-pass +//@ known-bug: #100041 +//@ check-pass // FIXME(inherent_associated_types): This should fail. #![feature(inherent_associated_types)] @@ -15,4 +15,3 @@ impl Foo { } fn main() -> Foo::Bar::> {} -//[next]~^ ERROR the size for values of type `[u32]` cannot be known at compilation time diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr index 05f5449dbc8b..85ac98f40501 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr @@ -7,7 +7,7 @@ LL | type Loop = Loop; = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Loop` - --> $DIR/inherent-impls-overflow.rs:10:1 + --> $DIR/inherent-impls-overflow.rs:12:1 | LL | impl Loop {} | ^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | impl Loop {} = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:14:17 + --> $DIR/inherent-impls-overflow.rs:17:17 | LL | type Poly0 = Poly1<(T,)>; | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | type Poly0 = Poly1<(T,)>; = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:17:17 + --> $DIR/inherent-impls-overflow.rs:21:17 | LL | type Poly1 = Poly0<(T,)>; | ^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | type Poly1 = Poly0<(T,)>; = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:21:1 + --> $DIR/inherent-impls-overflow.rs:26:1 | LL | impl Poly0<()> {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr index 4f1d339bc999..e94f29de44f0 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr @@ -1,11 +1,31 @@ error[E0271]: type mismatch resolving `Loop normalizes-to _` - --> $DIR/inherent-impls-overflow.rs:10:6 + --> $DIR/inherent-impls-overflow.rs:8:13 + | +LL | type Loop = Loop; + | ^^^^ types differ + +error[E0271]: type mismatch resolving `Loop normalizes-to _` + --> $DIR/inherent-impls-overflow.rs:12:1 + | +LL | impl Loop {} + | ^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `Loop normalizes-to _` + --> $DIR/inherent-impls-overflow.rs:12:6 | LL | impl Loop {} | ^^^^ types differ +error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _` + --> $DIR/inherent-impls-overflow.rs:17:17 + | +LL | type Poly0 = Poly1<(T,)>; + | ^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) + error: type parameter `T` is only used recursively - --> $DIR/inherent-impls-overflow.rs:14:24 + --> $DIR/inherent-impls-overflow.rs:17:24 | LL | type Poly0 = Poly1<(T,)>; | - ^ @@ -15,8 +35,16 @@ LL | type Poly0 = Poly1<(T,)>; = help: consider removing `T` or referring to it in the body of the type alias = note: all type parameters must be used in a non-recursive way in order to constrain their variance +error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _` + --> $DIR/inherent-impls-overflow.rs:21:17 + | +LL | type Poly1 = Poly0<(T,)>; + | ^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) + error: type parameter `T` is only used recursively - --> $DIR/inherent-impls-overflow.rs:17:24 + --> $DIR/inherent-impls-overflow.rs:21:24 | LL | type Poly1 = Poly0<(T,)>; | - ^ @@ -27,14 +55,22 @@ LL | type Poly1 = Poly0<(T,)>; = note: all type parameters must be used in a non-recursive way in order to constrain their variance error[E0275]: overflow evaluating the requirement `Poly0<()> == _` - --> $DIR/inherent-impls-overflow.rs:21:6 + --> $DIR/inherent-impls-overflow.rs:26:1 + | +LL | impl Poly0<()> {} + | ^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) + +error[E0275]: overflow evaluating the requirement `Poly0<()> == _` + --> $DIR/inherent-impls-overflow.rs:26:6 | LL | impl Poly0<()> {} | ^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) -error: aborting due to 4 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0271, E0275. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs index 0d5ec7d15307..b4a347cb098c 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs @@ -5,21 +5,27 @@ #![feature(lazy_type_alias)] #![allow(incomplete_features)] -type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop` +type Loop = Loop; +//[current]~^ ERROR overflow normalizing the type alias `Loop` +//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _` impl Loop {} //[current]~^ ERROR overflow normalizing the type alias `Loop` //[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _` +//[next]~| ERROR type mismatch resolving `Loop normalizes-to _` type Poly0 = Poly1<(T,)>; //[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` //[next]~^^ ERROR type parameter `T` is only used recursively +//[next]~| ERROR overflow evaluating the requirement type Poly1 = Poly0<(T,)>; //[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` //[next]~^^ ERROR type parameter `T` is only used recursively +//[next]~| ERROR overflow evaluating the requirement impl Poly0<()> {} //[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` //[next]~^^ ERROR overflow evaluating the requirement `Poly0<()> == _` +//[next]~| ERROR overflow evaluating the requirement fn main() {} diff --git a/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr b/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr index 2d42fedae438..e1ae981b2492 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied - --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:11 + --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:22 | LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()` | help: this trait has no implementations, consider adding one --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1 diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 8fe53d6773b9..fe336766891d 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -19,5 +19,6 @@ impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} //~^ ERROR cannot find type `Missing` in this scope //~| ERROR the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied +//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index d2a58e95629a..45fa33dff52f 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,6 +26,18 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } +error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied + --> $DIR/issue-118950-root-region.rs:19:9 + | +LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-118950-root-region.rs:8:1 + | +LL | trait ToUnit<'a> { + | ^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied --> $DIR/issue-118950-root-region.rs:19:47 | @@ -37,7 +49,7 @@ help: consider further restricting type parameter `T` with trait `Overlap` LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap, T: Overlap fn(Assoc<'a, T>)> {} | ++++++++++++++++++++++++++++++++++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr index 32a7766a638d..72be10367dac 100644 --- a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr +++ b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `(): Wf` is not satisfied - --> $DIR/non-wf-in-coerce-pointers.rs:8:17 + --> $DIR/non-wf-in-coerce-pointers.rs:8:8 | LL | f: &'static <() as Wf>::Assoc, - | ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()` | help: this trait has no implementations, consider adding one --> $DIR/non-wf-in-coerce-pointers.rs:3:1 diff --git a/tests/ui/wf/check-wf-of-normalized-signature.rs b/tests/ui/wf/check-wf-of-normalized-signature.rs new file mode 100644 index 000000000000..5fda69601d99 --- /dev/null +++ b/tests/ui/wf/check-wf-of-normalized-signature.rs @@ -0,0 +1,24 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for . +// Ensure that we check the well-formedness of `::Output` after normalizing +// the type to `()`, since we only imply outlives bounds from the normalized signature, so we +// don't know (e.g.) that `&mut T` is WF. + + +trait Mode { + type Output; + fn from_mut(_r: &mut Self::Output) -> Self::Output<&mut T>; +} + +struct Check; + +impl Mode for Check { + type Output = (); + fn from_mut(_r: &mut Self::Output) -> Self::Output<&mut T> {} +} + +fn main() {} diff --git a/tests/ui/wf/wf-normalization-sized.next.stderr b/tests/ui/wf/wf-normalization-sized.next.stderr index 66c4f214415d..804dd0a252d1 100644 --- a/tests/ui/wf/wf-normalization-sized.next.stderr +++ b/tests/ui/wf/wf-normalization-sized.next.stderr @@ -8,7 +8,7 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); = note: slice and array elements must have `Sized` type error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/wf-normalization-sized.rs:22:11 + --> $DIR/wf-normalization-sized.rs:21:11 | LL | const _: as WellUnformed>::RequestNormalize = (); | ^^^^^^^^ doesn't have a size known at compile-time @@ -17,27 +17,6 @@ LL | const _: as WellUnformed>::RequestNormalize = (); note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time - --> $DIR/wf-normalization-sized.rs:19:11 - | -LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); - | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]` - = note: slice and array elements must have `Sized` type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/wf-normalization-sized.rs:22:11 - | -LL | const _: as WellUnformed>::RequestNormalize = (); - | ^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `str` -note: required by an implicit `Sized` bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-normalization-sized.rs b/tests/ui/wf/wf-normalization-sized.rs index 5396cc8b32a8..e695fd93fb0e 100644 --- a/tests/ui/wf/wf-normalization-sized.rs +++ b/tests/ui/wf/wf-normalization-sized.rs @@ -18,9 +18,7 @@ impl WellUnformed for T { const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); //[next]~^ ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time -//[next]~| ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time const _: as WellUnformed>::RequestNormalize = (); //[next]~^ ERROR the size for values of type `str` cannot be known at compilation time -//[next]~| ERROR the size for values of type `str` cannot be known at compilation time fn main() {} From fa6d0d1ba263c02d1fd660c06f3918ea6e591ce7 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Sun, 4 May 2025 00:04:38 -0400 Subject: [PATCH 170/262] Use more accurate ELF flags on MIPS --- .../rustc_codegen_ssa/src/back/metadata.rs | 55 ++++++++++--------- compiler/rustc_target/src/spec/mod.rs | 9 ++- .../spec/targets/mips64_openwrt_linux_musl.rs | 1 + .../targets/mips64_unknown_linux_gnuabi64.rs | 1 + .../targets/mips64_unknown_linux_muslabi64.rs | 1 + .../mips64el_unknown_linux_gnuabi64.rs | 1 + .../mips64el_unknown_linux_muslabi64.rs | 7 ++- .../mipsisa64r6_unknown_linux_gnuabi64.rs | 1 + .../mipsisa64r6el_unknown_linux_gnuabi64.rs | 1 + 9 files changed, 50 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ebcccf1b97d9..2739f3844b53 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -270,45 +270,50 @@ pub(super) fn elf_os_abi(sess: &Session) -> u8 { pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { match architecture { - Architecture::Mips => { - let arch = match sess.target.options.cpu.as_ref() { - "mips1" => elf::EF_MIPS_ARCH_1, - "mips2" => elf::EF_MIPS_ARCH_2, + Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => { + let is_32bit = architecture == Architecture::Mips; + let mut e_flags = match sess.target.options.cpu.as_ref() { + "mips1" if is_32bit => elf::EF_MIPS_ARCH_1, + "mips2" if is_32bit => elf::EF_MIPS_ARCH_2, "mips3" => elf::EF_MIPS_ARCH_3, "mips4" => elf::EF_MIPS_ARCH_4, "mips5" => elf::EF_MIPS_ARCH_5, - s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6, - _ => elf::EF_MIPS_ARCH_32R2, + "mips32r2" if is_32bit => elf::EF_MIPS_ARCH_32R2, + "mips32r6" if is_32bit => elf::EF_MIPS_ARCH_32R6, + "mips64r2" if !is_32bit => elf::EF_MIPS_ARCH_64R2, + "mips64r6" if !is_32bit => elf::EF_MIPS_ARCH_64R6, + s if s.starts_with("mips32") && !is_32bit => { + sess.dcx().fatal(format!("invalid CPU `{}` for 64-bit MIPS target", s)) + } + s if s.starts_with("mips64") && is_32bit => { + sess.dcx().fatal(format!("invalid CPU `{}` for 32-bit MIPS target", s)) + } + _ if is_32bit => elf::EF_MIPS_ARCH_32R2, + _ => elf::EF_MIPS_ARCH_64R2, }; - let mut e_flags = elf::EF_MIPS_CPIC | arch; - - // If the ABI is explicitly given, use it or default to O32. - match sess.target.options.llvm_abiname.to_lowercase().as_str() { - "n32" => e_flags |= elf::EF_MIPS_ABI2, - "o32" => e_flags |= elf::EF_MIPS_ABI_O32, - _ => e_flags |= elf::EF_MIPS_ABI_O32, + // If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS, + // which is the only option. + match sess.target.options.llvm_abiname.as_ref() { + "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, + "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2, + "n64" if !is_32bit => {} + "" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, + "" => sess.dcx().fatal("LLVM ABI must be specifed for 64-bit MIPS targets"), + s if is_32bit => { + sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s)) + } + s => sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 64-bit MIPS target", s)), }; if sess.target.options.relocation_model != RelocModel::Static { - e_flags |= elf::EF_MIPS_PIC; + e_flags |= elf::EF_MIPS_PIC | elf::EF_MIPS_CPIC; } if sess.target.options.cpu.contains("r6") { e_flags |= elf::EF_MIPS_NAN2008; } e_flags } - Architecture::Mips64 => { - // copied from `mips64el-linux-gnuabi64-gcc foo.c -c` - let e_flags = elf::EF_MIPS_CPIC - | elf::EF_MIPS_PIC - | if sess.target.options.cpu.contains("r6") { - elf::EF_MIPS_ARCH_64R6 | elf::EF_MIPS_NAN2008 - } else { - elf::EF_MIPS_ARCH_64R2 - }; - e_flags - } Architecture::Riscv32 | Architecture::Riscv64 => { // Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc let mut e_flags: u32 = 0x0; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 37ea0d6e7b58..a3f36e51f32c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3567,7 +3567,14 @@ impl Target { "x86" => (Architecture::I386, None), "s390x" => (Architecture::S390x, None), "mips" | "mips32r6" => (Architecture::Mips, None), - "mips64" | "mips64r6" => (Architecture::Mips64, None), + "mips64" | "mips64r6" => ( + if self.options.llvm_abiname.as_ref() == "n32" { + Architecture::Mips64_N32 + } else { + Architecture::Mips64 + }, + None, + ), "x86_64" => ( if self.pointer_width == 32 { Architecture::X86_64_X32 diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs index 71b3fbe00b2f..508abc010184 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs @@ -27,6 +27,7 @@ pub(crate) fn target() -> Target { abi: "abi64".into(), endian: Endian::Big, mcount: "_mcount".into(), + llvm_abiname: "n64".into(), ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs index b130ca29c7f0..a26350ff2250 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs @@ -22,6 +22,7 @@ pub(crate) fn target() -> Target { features: "+mips64r2,+xgot".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), + llvm_abiname: "n64".into(), ..base::linux_gnu::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs index 4ea7c7bff44a..fd5095030530 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs @@ -25,6 +25,7 @@ pub(crate) fn target() -> Target { mcount: "_mcount".into(), // FIXME(compiler-team#422): musl targets should be dynamically linked by default. crt_static_default: true, + llvm_abiname: "n64".into(), ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs index a9afea27ef34..19bceadc6223 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs @@ -19,6 +19,7 @@ pub(crate) fn target() -> Target { features: "+mips64r2,+xgot".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), + llvm_abiname: "n64".into(), ..base::linux_gnu::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs index 7bdd9edda70c..aa087b1a35af 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs @@ -19,6 +19,11 @@ pub(crate) fn target() -> Target { pointer_width: 64, data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: "mips64".into(), - options: TargetOptions { abi: "abi64".into(), mcount: "_mcount".into(), ..base }, + options: TargetOptions { + abi: "abi64".into(), + mcount: "_mcount".into(), + llvm_abiname: "n64".into(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs index 3eefa27ea04b..cdd5f6b84365 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -22,6 +22,7 @@ pub(crate) fn target() -> Target { features: "+mips64r6".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), + llvm_abiname: "n64".into(), ..base::linux_gnu::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs index 0887180791c7..88879a25818b 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -19,6 +19,7 @@ pub(crate) fn target() -> Target { features: "+mips64r6".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), + llvm_abiname: "n64".into(), ..base::linux_gnu::opts() }, From 57941afb23ef59e956d2a5ef6604369543edf419 Mon Sep 17 00:00:00 2001 From: smrobtzz <148004237+smrobtzz@users.noreply.github.com> Date: Mon, 5 May 2025 00:21:14 -0400 Subject: [PATCH 171/262] Apply suggestions from code review Co-authored-by: Jubilee --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 13 ++++++++++++- compiler/rustc_target/src/spec/mod.rs | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 2739f3844b53..ec46c71b0e40 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -271,6 +271,8 @@ pub(super) fn elf_os_abi(sess: &Session) -> u8 { pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { match architecture { Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => { + // "N32" indicates an "ILP32" data model on a 64-bit MIPS CPU + // like SPARC's "v8+", x86_64's "x32", or the watchOS "arm64_32". let is_32bit = architecture == Architecture::Mips; let mut e_flags = match sess.target.options.cpu.as_ref() { "mips1" if is_32bit => elf::EF_MIPS_ARCH_1, @@ -293,7 +295,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { }; // If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS, - // which is the only option. + // which is the only "true" 32-bit option that LLVM supports. match sess.target.options.llvm_abiname.as_ref() { "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2, @@ -307,6 +309,15 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { }; if sess.target.options.relocation_model != RelocModel::Static { + // PIC means position-independent code. CPIC means "calls PIC". + // CPIC was mutually exclusive with PIC according to + // the SVR4 MIPS ABI https://refspecs.linuxfoundation.org/elf/mipsabi.pdf + // and should have only appeared on static objects with dynamically calls. + // At some point someone (GCC?) decided to set CPIC even for PIC. + // Nowadays various things expect both set on the same object file + // and may even error if you mix CPIC and non-CPIC object files, + // despite that being the entire point of the CPIC ABI extension! + // As we are in Rome, we do as the Romans do. e_flags |= elf::EF_MIPS_PIC | elf::EF_MIPS_CPIC; } if sess.target.options.cpu.contains("r6") { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index a3f36e51f32c..303be54a6d78 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3568,6 +3568,11 @@ impl Target { "s390x" => (Architecture::S390x, None), "mips" | "mips32r6" => (Architecture::Mips, None), "mips64" | "mips64r6" => ( + // While there are currently no builtin targets + // using the N32 ABI, it is possible to specify + // it using a custom target specification. N32 + // is an ILP32 ABI like the Aarch64_Ilp32 + // and X86_64_X32 cases above and below this one. if self.options.llvm_abiname.as_ref() == "n32" { Architecture::Mips64_N32 } else { From 872387195dce76176b92b954e1ba82bfe9fba928 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 5 May 2025 19:01:06 +0200 Subject: [PATCH 172/262] Update books --- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/reference b/src/doc/reference index 3bf3402aea98..387392674d74 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 3bf3402aea982b876eb56c87da17b0685c6461d5 +Subproject commit 387392674d74656f7cb437c05a96f0c52ea8e601 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 0d7964d5b22c..8a8918c69853 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 0d7964d5b22cf920237ef1282d869564b4883b88 +Subproject commit 8a8918c698534547fa8a1a693cb3e7277f0bfb2f From 6a7996e30325e28215b318feb7cc56bcff0e2bb5 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 19 Apr 2025 11:52:18 +0200 Subject: [PATCH 173/262] Take into-account `-Zremap-path-scope` when embedding filenames --- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 - compiler/rustc_session/src/config.rs | 8 +- compiler/rustc_span/src/lib.rs | 34 +++----- compiler/rustc_span/src/source_map.rs | 80 ++++++++++--------- compiler/rustc_span/src/source_map/tests.rs | 73 +++++++++++++++++ .../run-make/remap-path-prefix-dwarf/rmake.rs | 53 ++++++++++++ .../src/print_value.rs | 7 ++ .../remap-path-prefix-dwarf/src/some_value.rs | 6 ++ tests/run-make/remap-path-prefix/rmake.rs | 6 +- 9 files changed, 205 insertions(+), 64 deletions(-) create mode 100644 tests/run-make/remap-path-prefix-dwarf/src/print_value.rs create mode 100644 tests/run-make/remap-path-prefix-dwarf/src/some_value.rs diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3ea61d1b40a6..e4cf58fccda2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -551,8 +551,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match source_file.name { FileName::Real(ref original_file_name) => { - // FIXME: This should probably to conditionally remapped under - // a RemapPathScopeComponents but which one? let adapted_file_name = source_map .path_mapping() .to_embeddable_absolute_path(original_file_name.clone(), working_directory); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e2d36f6a4e2f..ccb1e9509604 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -24,7 +24,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::{ - FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym, + FileName, FileNameDisplayPreference, FileNameEmbeddablePreference, RealFileName, + SourceFileHashAlgorithm, Symbol, sym, }; use rustc_target::spec::{ FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple, @@ -1316,6 +1317,11 @@ fn file_path_mapping( } else { FileNameDisplayPreference::Local }, + if unstable_opts.remap_path_scope.is_all() { + FileNameEmbeddablePreference::RemappedOnly + } else { + FileNameEmbeddablePreference::LocalAndRemapped + }, ) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 9722031f209b..6fcf77e31a22 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -224,7 +224,7 @@ pub fn with_metavar_spans(f: impl FnOnce(&MetavarSpansMap) -> R) -> R { // FIXME: We should use this enum or something like it to get rid of the // use of magic `/rust/1.x/...` paths across the board. -#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)] +#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable)] pub enum RealFileName { LocalPath(PathBuf), /// For remapped paths (namely paths into libstd that have been mapped @@ -250,28 +250,6 @@ impl Hash for RealFileName { } } -// This is functionally identical to #[derive(Encodable)], with the exception of -// an added assert statement -impl Encodable for RealFileName { - fn encode(&self, encoder: &mut S) { - match *self { - RealFileName::LocalPath(ref local_path) => { - encoder.emit_u8(0); - local_path.encode(encoder); - } - - RealFileName::Remapped { ref local_path, ref virtual_name } => { - encoder.emit_u8(1); - // For privacy and build reproducibility, we must not embed host-dependant path - // in artifacts if they have been remapped by --remap-path-prefix - assert!(local_path.is_none()); - local_path.encode(encoder); - virtual_name.encode(encoder); - } - } - } -} - impl RealFileName { /// Returns the path suitable for reading from the file system on the local host, /// if this information exists. @@ -368,6 +346,16 @@ impl From for FileName { } } +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +pub enum FileNameEmbeddablePreference { + /// If a remapped path is available, only embed the `virtual_path` and omit the `local_path`. + /// + /// Otherwise embed the local-path into the `virtual_path`. + RemappedOnly, + /// Embed the original path as well as its remapped `virtual_path` component if available. + LocalAndRemapped, +} + #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] pub enum FileNameDisplayPreference { /// Display the path after the application of rewrite rules provided via `--remap-path-prefix`. diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 0273bb040f43..8a3644163caf 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -1108,18 +1108,28 @@ pub fn get_source_map() -> Option> { pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, filename_display_for_diagnostics: FileNameDisplayPreference, + filename_embeddable_preference: FileNameEmbeddablePreference, } impl FilePathMapping { pub fn empty() -> FilePathMapping { - FilePathMapping::new(Vec::new(), FileNameDisplayPreference::Local) + FilePathMapping::new( + Vec::new(), + FileNameDisplayPreference::Local, + FileNameEmbeddablePreference::RemappedOnly, + ) } pub fn new( mapping: Vec<(PathBuf, PathBuf)>, filename_display_for_diagnostics: FileNameDisplayPreference, + filename_embeddable_preference: FileNameEmbeddablePreference, ) -> FilePathMapping { - FilePathMapping { mapping, filename_display_for_diagnostics } + FilePathMapping { + mapping, + filename_display_for_diagnostics, + filename_embeddable_preference, + } } /// Applies any path prefix substitution as defined by the mapping. @@ -1217,11 +1227,13 @@ impl FilePathMapping { ) -> RealFileName { match file_path { // Anything that's already remapped we don't modify, except for erasing - // the `local_path` portion. - RealFileName::Remapped { local_path: _, virtual_name } => { + // the `local_path` portion (if desired). + RealFileName::Remapped { local_path, virtual_name } => { RealFileName::Remapped { - // We do not want any local path to be exported into metadata - local_path: None, + local_path: match self.filename_embeddable_preference { + FileNameEmbeddablePreference::RemappedOnly => None, + FileNameEmbeddablePreference::LocalAndRemapped => local_path, + }, // We use the remapped name verbatim, even if it looks like a relative // path. The assumption is that the user doesn't want us to further // process paths that have gone through remapping. @@ -1231,12 +1243,18 @@ impl FilePathMapping { RealFileName::LocalPath(unmapped_file_path) => { // If no remapping has been applied yet, try to do so - let (new_path, was_remapped) = self.map_prefix(unmapped_file_path); + let (new_path, was_remapped) = self.map_prefix(&unmapped_file_path); if was_remapped { // It was remapped, so don't modify further return RealFileName::Remapped { - local_path: None, virtual_name: new_path.into_owned(), + // But still provide the local path if desired + local_path: match self.filename_embeddable_preference { + FileNameEmbeddablePreference::RemappedOnly => None, + FileNameEmbeddablePreference::LocalAndRemapped => { + Some(unmapped_file_path) + } + }, }; } @@ -1252,17 +1270,23 @@ impl FilePathMapping { match working_directory { RealFileName::LocalPath(unmapped_working_dir_abs) => { - let file_path_abs = unmapped_working_dir_abs.join(unmapped_file_path_rel); + let unmapped_file_path_abs = + unmapped_working_dir_abs.join(unmapped_file_path_rel); // Although neither `working_directory` nor the file name were subject // to path remapping, the concatenation between the two may be. Hence // we need to do a remapping here. - let (file_path_abs, was_remapped) = self.map_prefix(file_path_abs); + let (file_path_abs, was_remapped) = + self.map_prefix(&unmapped_file_path_abs); if was_remapped { RealFileName::Remapped { - // Erase the actual path - local_path: None, virtual_name: file_path_abs.into_owned(), + local_path: match self.filename_embeddable_preference { + FileNameEmbeddablePreference::RemappedOnly => None, + FileNameEmbeddablePreference::LocalAndRemapped => { + Some(unmapped_file_path_abs) + } + }, } } else { // No kind of remapping applied to this path, so @@ -1271,15 +1295,20 @@ impl FilePathMapping { } } RealFileName::Remapped { - local_path: _, + local_path, virtual_name: remapped_working_dir_abs, } => { // If working_directory has been remapped, then we emit // Remapped variant as the expanded path won't be valid RealFileName::Remapped { - local_path: None, virtual_name: Path::new(remapped_working_dir_abs) - .join(unmapped_file_path_rel), + .join(&unmapped_file_path_rel), + local_path: match self.filename_embeddable_preference { + FileNameEmbeddablePreference::RemappedOnly => None, + FileNameEmbeddablePreference::LocalAndRemapped => local_path + .as_ref() + .map(|local_path| local_path.join(unmapped_file_path_rel)), + }, } } } @@ -1287,27 +1316,6 @@ impl FilePathMapping { } } - /// Expand a relative path to an absolute path **without** remapping taken into account. - /// - /// The resulting `RealFileName` will have its `virtual_path` portion erased if - /// possible (i.e. if there's also a remapped path). - pub fn to_local_embeddable_absolute_path( - &self, - file_path: RealFileName, - working_directory: &RealFileName, - ) -> RealFileName { - let file_path = file_path.local_path_if_available(); - if file_path.is_absolute() { - // No remapping has applied to this path and it is absolute, - // so the working directory cannot influence it either, so - // we are done. - return RealFileName::LocalPath(file_path.to_path_buf()); - } - debug_assert!(file_path.is_relative()); - let working_directory = working_directory.local_path_if_available(); - RealFileName::LocalPath(Path::new(working_directory).join(file_path)) - } - /// Attempts to (heuristically) reverse a prefix mapping. /// /// Returns [`Some`] if there is exactly one mapping where the "to" part is diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 957f55e39138..589c2a363548 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -305,6 +305,7 @@ fn path_prefix_remapping() { let mapping = &FilePathMapping::new( vec![(path("abc/def"), path("foo"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs")); @@ -316,6 +317,7 @@ fn path_prefix_remapping() { let mapping = &FilePathMapping::new( vec![(path("abc/def"), path("/foo"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs")); @@ -327,6 +329,7 @@ fn path_prefix_remapping() { let mapping = &FilePathMapping::new( vec![(path("/abc/def"), path("foo"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs")); @@ -338,6 +341,7 @@ fn path_prefix_remapping() { let mapping = &FilePathMapping::new( vec![(path("/abc/def"), path("/foo"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs")); @@ -351,6 +355,7 @@ fn path_prefix_remapping_expand_to_absolute() { let mapping = &FilePathMapping::new( vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); let working_directory = path("/foo"); let working_directory = RealFileName::Remapped { @@ -448,6 +453,71 @@ fn path_prefix_remapping_expand_to_absolute() { ); } +#[test] +fn path_prefix_remapping_expand_to_absolute_and_local() { + // "virtual" working directory is relative path + let mapping = &FilePathMapping::new( + vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))], + FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::LocalAndRemapped, + ); + let working_directory = path("/foo"); + let working_directory = RealFileName::Remapped { + local_path: Some(working_directory.clone()), + virtual_name: mapping.map_prefix(working_directory).0.into_owned(), + }; + + assert_eq!(working_directory.remapped_path_if_available(), path("FOO")); + + // Unmapped absolute path + assert_eq!( + mapping.to_embeddable_absolute_path( + RealFileName::LocalPath(path("/foo/src/main.rs")), + &working_directory + ), + RealFileName::Remapped { + local_path: Some(path("/foo/src/main.rs")), + virtual_name: path("FOO/src/main.rs") + } + ); + + // Unmapped absolute path with unrelated working directory + assert_eq!( + mapping.to_embeddable_absolute_path( + RealFileName::LocalPath(path("/bar/src/main.rs")), + &working_directory + ), + RealFileName::Remapped { + local_path: Some(path("/bar/src/main.rs")), + virtual_name: path("BAR/src/main.rs") + } + ); + + // Already remapped absolute path, with unrelated working directory + assert_eq!( + mapping.to_embeddable_absolute_path( + RealFileName::Remapped { + local_path: Some(path("/bar/src/main.rs")), + virtual_name: path("BAR/src/main.rs"), + }, + &working_directory + ), + RealFileName::Remapped { + local_path: Some(path("/bar/src/main.rs")), + virtual_name: path("BAR/src/main.rs") + } + ); + + // Already remapped relative path + assert_eq!( + mapping.to_embeddable_absolute_path( + RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }, + &working_directory + ), + RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") } + ); +} + #[test] fn path_prefix_remapping_reverse() { // Ignores options without alphanumeric chars. @@ -455,6 +525,7 @@ fn path_prefix_remapping_reverse() { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/")), (path("def"), path("."))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None); @@ -466,6 +537,7 @@ fn path_prefix_remapping_reverse() { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None); @@ -476,6 +548,7 @@ fn path_prefix_remapping_reverse() { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))], FileNameDisplayPreference::Remapped, + FileNameEmbeddablePreference::RemappedOnly, ); assert_eq!( diff --git a/tests/run-make/remap-path-prefix-dwarf/rmake.rs b/tests/run-make/remap-path-prefix-dwarf/rmake.rs index ede1d6157425..3d6ca014fc2a 100644 --- a/tests/run-make/remap-path-prefix-dwarf/rmake.rs +++ b/tests/run-make/remap-path-prefix-dwarf/rmake.rs @@ -91,6 +91,59 @@ fn main() { )), dwarf_test: DwarfDump::ParentTest, }); + + check_dwarf_deps("macro", DwarfDump::AvoidSrcPath); + check_dwarf_deps("diagnostics", DwarfDump::AvoidSrcPath); + check_dwarf_deps("macro,diagnostics", DwarfDump::AvoidSrcPath); + check_dwarf_deps("object", DwarfDump::ContainsSrcPath); +} + +#[track_caller] +fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) { + // build some_value.rs + let mut rustc_sm = rustc(); + rustc_sm.input(cwd().join("src/some_value.rs")); + rustc_sm.arg("-Cdebuginfo=2"); + rustc_sm.arg(format!("-Zremap-path-scope={}", scope)); + rustc_sm.arg("--remap-path-prefix"); + rustc_sm.arg(format!("{}=/REMAPPED", cwd().display())); + rustc_sm.arg("-Csplit-debuginfo=off"); + rustc_sm.run(); + + // build print_value.rs + let print_value_rlib = rust_lib_name(&format!("print_value.{scope}")); + let mut rustc_pv = rustc(); + rustc_pv.input(cwd().join("src/print_value.rs")); + rustc_pv.output(&print_value_rlib); + rustc_pv.arg("-Cdebuginfo=2"); + rustc_pv.arg(format!("-Zremap-path-scope={}", scope)); + rustc_pv.arg("--remap-path-prefix"); + rustc_pv.arg(format!("{}=/REMAPPED", cwd().display())); + rustc_pv.arg("-Csplit-debuginfo=off"); + rustc_pv.run(); + + match dwarf_test { + DwarfDump::AvoidSrcPath => { + llvm_dwarfdump() + .input(print_value_rlib) + .run() + .assert_stdout_not_contains("REMAPPED/src/some_value.rs") + .assert_stdout_not_contains("REMAPPED/src/print_value.rs") + .assert_stdout_not_contains("REMAPPED/REMAPPED") + .assert_stdout_contains(cwd().join("src/some_value.rs").display().to_string()) + .assert_stdout_contains(cwd().join("src/print_value.rs").display().to_string()); + } + DwarfDump::ContainsSrcPath => { + llvm_dwarfdump() + .input(print_value_rlib) + .run() + .assert_stdout_contains("REMAPPED/src/some_value.rs") + .assert_stdout_contains("REMAPPED/src/print_value.rs") + .assert_stdout_not_contains(cwd().join("src/some_value.rs").display().to_string()) + .assert_stdout_not_contains(cwd().join("src/print_value.rs").display().to_string()); + } + _ => unreachable!(), + } } #[track_caller] diff --git a/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs b/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs new file mode 100644 index 000000000000..f7653025ba5a --- /dev/null +++ b/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs @@ -0,0 +1,7 @@ +#![crate_type = "rlib"] + +extern crate some_value; + +pub fn print_value() { + println!("{}", some_value::get_some_value()); +} diff --git a/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs b/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs new file mode 100644 index 000000000000..aa95a1bdf73b --- /dev/null +++ b/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] + +#[inline] +pub fn get_some_value() -> i32 { + 42 +} diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index aeb30e72d5bf..b4f7f4769b5b 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -47,10 +47,10 @@ fn main() { out_object.run(); rmeta_contains("/the/aux/lib.rs"); - rmeta_not_contains("auxiliary"); + rmeta_contains("auxiliary"); out_macro.run(); rmeta_contains("/the/aux/lib.rs"); - rmeta_not_contains("auxiliary"); + rmeta_contains("auxiliary"); out_diagobj.run(); rmeta_contains("/the/aux/lib.rs"); rmeta_not_contains("auxiliary"); @@ -58,6 +58,7 @@ fn main() { //FIXME(Oneirical): These could be generalized into run_make_support // helper functions. +#[track_caller] fn rmeta_contains(expected: &str) { // Normalize to account for path differences in Windows. if !bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) { @@ -69,6 +70,7 @@ fn rmeta_contains(expected: &str) { } } +#[track_caller] fn rmeta_not_contains(expected: &str) { // Normalize to account for path differences in Windows. if bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) { From 7fc84ac964b45955cc9beb7ec269d3d06a3591ab Mon Sep 17 00:00:00 2001 From: Skgland Date: Mon, 5 May 2025 20:40:44 +0200 Subject: [PATCH 174/262] expand comment --- .../type-inference/regression-issue-81317.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/ui/type-inference/regression-issue-81317.rs b/tests/ui/type-inference/regression-issue-81317.rs index 50deb013d4b1..39c91948426b 100644 --- a/tests/ui/type-inference/regression-issue-81317.rs +++ b/tests/ui/type-inference/regression-issue-81317.rs @@ -1,4 +1,33 @@ // Regression test for #81317: type can no longer be infered as of 1.49 +// +// The problem is that the xor operator and the index.into() each have two candidate impls that could apply +// { S as BitXor, S as BitXor<&'a S> } for xor and +// { T::I as Into, T::I as Into } for index.into() +// previously inference was able to infer that the only valid combination was +// S as BitXor and T::I as Into +// +// after rust-lang/rust#73905 this is no longer infered +// +// the error message could be better e.g. when iv is unused or has an an explicitly specified type S +// there is currently the following help message +// +// error[E0284]: type annotations needed +// --> src/main.rs:13:24 +// | +// 42 | let iv = S ^ index.into(); +// | - ^^^^ +// | | +// | type must be known at this point +// | +// = note: cannot satisfy `>::Output == _` +// help: try using a fully qualified path to specify the expected types +// | +// 42 - let iv = S ^ index.into(); +// 42 + let iv = S ^ <::I as Into>::into(index); +// +// this is better as it's actually sufficent to fix the problem, +// while just specifying the type of iv as currently suggested is insufficent +// //@ check-fail use std::ops::BitXor; From aeab2819f650d180eb0e7238ff8a0733af70b3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 5 May 2025 20:49:09 +0200 Subject: [PATCH 175/262] Tweak index chunk allocation --- .../rustc_query_system/src/dep_graph/serialized.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 648823edb189..b5eda7b04a7f 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -572,14 +572,18 @@ impl EncoderState { #[inline] fn next_index(&self, local: &mut LocalEncoderState) -> DepNodeIndex { if local.remaining_node_index == 0 { - let count = 256; + const COUNT: u32 = 256; - // We assume that there won't be enough active threads to overflow u64 from u32::MAX here. - assert!(self.next_node_index.load(Ordering::Relaxed) <= u32::MAX as u64); + // We assume that there won't be enough active threads to overflow `u64` from `u32::MAX` here. + // This can exceed u32::MAX by at most `N` * `COUNT` where `N` is the thread pool count since + // `try_into().unwrap()` will make threads panic when `self.next_node_index` exceeds u32::MAX. local.next_node_index = - self.next_node_index.fetch_add(count, Ordering::Relaxed).try_into().unwrap(); + self.next_node_index.fetch_add(COUNT as u64, Ordering::Relaxed).try_into().unwrap(); - local.remaining_node_index = count as u32; + // Check that we'll stay within `u32` + local.next_node_index.checked_add(COUNT).unwrap(); + + local.remaining_node_index = COUNT; } DepNodeIndex::from_u32(local.next_node_index) From e1e8857d544b743419a8caddb7f4b5e0fb9610f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 5 May 2025 21:01:43 +0200 Subject: [PATCH 176/262] Add some comments about thread local indices --- compiler/rustc_query_system/src/dep_graph/serialized.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index b5eda7b04a7f..b01f65a5e454 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -12,7 +12,7 @@ //! node and edge count are stored at the end of the file, all the arrays can be //! pre-allocated with the right length. //! -//! The encoding of the de-pgraph is generally designed around the fact that fixed-size +//! The encoding of the dep-graph is generally designed around the fact that fixed-size //! reads of encoded data are generally faster than variable-sized reads. Ergo we adopt //! essentially the same varint encoding scheme used in the rmeta format; the edge lists //! for each node on the graph store a 2-bit integer which is the number of bytes per edge @@ -34,6 +34,10 @@ //! [`DepKind`], number of edges, and bytes per edge are all bit-packed together, if they fit. //! If the number of edges in this node does not fit in the bits available in the header, we //! store it directly after the header with leb128. +//! +//! Dep-graph indices are bulk allocated to threads inside `LocalEncoderState`. Having threads +//! own these indices helps avoid races when they are conditionally used when marking nodes green. +//! It also reduces congestion on the shared index count. use std::cell::RefCell; use std::cmp::max; From c0dfa44c485bb8a7a30f2b4b69827028b3d55c98 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 May 2025 17:19:23 +0000 Subject: [PATCH 177/262] Be a bit more relaxed about not yet constrained infer vars in closure upvar analysis --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 49 +++++++------------ tests/crashes/131758.rs | 11 ----- tests/ui/closures/opaque-upvar.rs | 19 +++++++ ...arg-constrained-after-closure-inference.rs | 16 ++++++ 4 files changed, 54 insertions(+), 41 deletions(-) delete mode 100644 tests/crashes/131758.rs create mode 100644 tests/ui/closures/opaque-upvar.rs create mode 100644 tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 17e13ec0a376..3493d359028d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -158,7 +158,7 @@ pub trait TypeInformationCtxt<'tcx> { fn resolve_vars_if_possible>>(&self, t: T) -> T; - fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; + fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error; @@ -191,8 +191,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { self.infcx.resolve_vars_if_possible(t) } - fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - (**self).try_structurally_resolve_type(sp, ty) + fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + (**self).structurally_resolve_type(sp, ty) } fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error { @@ -236,7 +236,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { self.0.maybe_typeck_results().expect("expected typeck results") } - fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { // FIXME: Maybe need to normalize here. ty } @@ -776,7 +776,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Select just those fields of the `with` // expression that will actually be used - match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() { + match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() { ty::Adt(adt, args) if adt.is_struct() => { // Consume those fields of the with expression that are needed. for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { @@ -1176,7 +1176,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// two operations: a dereference to reach the array data and then an index to /// jump forward to the relevant item. impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { - fn resolve_type_vars_or_bug( + fn expect_and_resolve_type( &self, id: HirId, ty: Option>, @@ -1185,12 +1185,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Some(ty) => { let ty = self.cx.resolve_vars_if_possible(ty); self.cx.error_reported_in_ty(ty)?; - if ty.is_ty_var() { - debug!("resolve_type_vars_or_bug: infer var from {:?}", ty); - Err(self.cx.report_bug(self.cx.tcx().hir_span(id), "encountered type variable")) - } else { - Ok(ty) - } + Ok(ty) } None => { // FIXME: We shouldn't be relying on the infcx being tainted. @@ -1201,15 +1196,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } fn node_ty(&self, hir_id: HirId) -> Result, Cx::Error> { - self.resolve_type_vars_or_bug(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) + self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) } fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { - self.resolve_type_vars_or_bug(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) + self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) } fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { - self.resolve_type_vars_or_bug( + self.expect_and_resolve_type( expr.hir_id, self.cx.typeck_results().expr_ty_adjusted_opt(expr), ) @@ -1264,10 +1259,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // a bind-by-ref means that the base_ty will be the type of the ident itself, // but what we want here is the type of the underlying value being borrowed. // So peel off one-level, turning the &T into T. - match self - .cx - .try_structurally_resolve_type(pat.span, base_ty) - .builtin_deref(false) + match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false) { Some(ty) => Ok(ty), None => { @@ -1513,10 +1505,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx if node_ty != place_ty && self .cx - .try_structurally_resolve_type( - self.cx.tcx().hir_span(base_place.hir_id), - place_ty, - ) + .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty) .is_impl_trait() { projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); @@ -1538,7 +1527,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let base_ty = self.expr_ty_adjusted(base)?; let ty::Ref(region, _, mutbl) = - *self.cx.try_structurally_resolve_type(base.span, base_ty).kind() + *self.cx.structurally_resolve_type(base.span, base_ty).kind() else { span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); }; @@ -1556,7 +1545,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let base_curr_ty = base_place.place.ty(); let deref_ty = match self .cx - .try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty) + .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty) .builtin_deref(true) { Some(ty) => ty, @@ -1584,7 +1573,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> Result { let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); let ty = self.cx.typeck_results().node_type(pat_hir_id); - let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else { + let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else { return Err(self .cx .report_bug(span, "struct or tuple struct pattern not applied to an ADT")); @@ -1616,7 +1605,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx span: Span, ) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); - match self.cx.try_structurally_resolve_type(span, ty).kind() { + match self.cx.structurally_resolve_type(span, ty).kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), _ => { self.cx @@ -1631,7 +1620,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Here `pat_hir_id` is the HirId of the pattern itself. fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); - match self.cx.try_structurally_resolve_type(span, ty).kind() { + match self.cx.structurally_resolve_type(span, ty).kind() { ty::Tuple(args) => Ok(args.len()), _ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")), } @@ -1820,7 +1809,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx PatKind::Slice(before, ref slice, after) => { let Some(element_ty) = self .cx - .try_structurally_resolve_type(pat.span, place_with_id.place.ty()) + .structurally_resolve_type(pat.span, place_with_id.place.ty()) .builtin_index() else { debug!("explicit index of non-indexable type {:?}", place_with_id); @@ -1890,7 +1879,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { - if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() { + if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() { // Note that if a non-exhaustive SingleVariant is defined in another crate, we need // to assume that more cases will be added to the variant in the future. This mean // that we should handle non-exhaustive SingleVariant the same way we would handle diff --git a/tests/crashes/131758.rs b/tests/crashes/131758.rs deleted file mode 100644 index 942c5fd7a502..000000000000 --- a/tests/crashes/131758.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #131758 -#![feature(unboxed_closures)] -trait Foo {} - -impl> Foo for T {} - -fn baz(_: T) {} - -fn main() { - baz(|x| ()); -} diff --git a/tests/ui/closures/opaque-upvar.rs b/tests/ui/closures/opaque-upvar.rs new file mode 100644 index 000000000000..90e7c9ccb465 --- /dev/null +++ b/tests/ui/closures/opaque-upvar.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . +// This is only an issue in the new solver, but I'm testing it in both solvers for now. +// This has to do with the fact that the recursive `walk_dir` is a revealing use, which has not +// yet been constrained from the defining use by the time that closure signature inference is +// performed. We don't really care, though, since anywhere we structurally match on a type in +// upvar analysis, we already call `structurally_resolve_type` right before `.kind()`. + +fn walk_dir(cb: &()) -> impl Sized { + || { + let fut = walk_dir(cb); + }; +} + +fn main() {} diff --git a/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs b/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs new file mode 100644 index 000000000000..343a27616d1d --- /dev/null +++ b/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs @@ -0,0 +1,16 @@ +#![feature(unboxed_closures)] + +//@ check-pass + +// Regression test for #131758. We only know the type of `x` after closure upvar +// inference is done, even if we don't need to structurally resolve the type of `x`. + +trait Foo {} + +impl> Foo for T {} + +fn baz(_: T) {} + +fn main() { + baz(|x| ()); +} From fb8784585eece42a22c782bb01c1c2f188f70505 Mon Sep 17 00:00:00 2001 From: Skgland Date: Mon, 5 May 2025 21:09:31 +0200 Subject: [PATCH 178/262] fix tidy and bless test --- tests/ui/type-inference/regression-issue-81317.rs | 12 +++++++----- .../ui/type-inference/regression-issue-81317.stderr | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/ui/type-inference/regression-issue-81317.rs b/tests/ui/type-inference/regression-issue-81317.rs index 39c91948426b..0b1266e6a0fd 100644 --- a/tests/ui/type-inference/regression-issue-81317.rs +++ b/tests/ui/type-inference/regression-issue-81317.rs @@ -1,6 +1,7 @@ // Regression test for #81317: type can no longer be infered as of 1.49 // -// The problem is that the xor operator and the index.into() each have two candidate impls that could apply +// The problem is that the xor operator and the index.into() call +// each have two candidate impls that could apply // { S as BitXor, S as BitXor<&'a S> } for xor and // { T::I as Into, T::I as Into } for index.into() // previously inference was able to infer that the only valid combination was @@ -8,13 +9,14 @@ // // after rust-lang/rust#73905 this is no longer infered // -// the error message could be better e.g. when iv is unused or has an an explicitly specified type S +// the error message could be better e.g. +// when iv is unused or has an an explicitly specified type S // there is currently the following help message // // error[E0284]: type annotations needed // --> src/main.rs:13:24 // | -// 42 | let iv = S ^ index.into(); +// 44 | let iv = S ^ index.into(); // | - ^^^^ // | | // | type must be known at this point @@ -22,8 +24,8 @@ // = note: cannot satisfy `>::Output == _` // help: try using a fully qualified path to specify the expected types // | -// 42 - let iv = S ^ index.into(); -// 42 + let iv = S ^ <::I as Into>::into(index); +// 44 - let iv = S ^ index.into(); +// 44 + let iv = S ^ <::I as Into>::into(index); // // this is better as it's actually sufficent to fix the problem, // while just specifying the type of iv as currently suggested is insufficent diff --git a/tests/ui/type-inference/regression-issue-81317.stderr b/tests/ui/type-inference/regression-issue-81317.stderr index d018a2c48545..fcd3fca06e18 100644 --- a/tests/ui/type-inference/regression-issue-81317.stderr +++ b/tests/ui/type-inference/regression-issue-81317.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/regression-issue-81317.rs:13:9 + --> $DIR/regression-issue-81317.rs:44:9 | LL | let iv = S ^ index.into(); | ^^ From 292aea50d876af5ca77d3c0233c836ff240d3bca Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 5 May 2025 15:13:40 -0700 Subject: [PATCH 179/262] Update mdbook to 0.4.49 This is a routine update to pull in some fixes and updates. Changelog: https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-0449 --- src/tools/rustbook/Cargo.lock | 4 ++-- src/tools/rustbook/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 81e0f6d572be..3b5b31bed14a 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -938,9 +938,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.48" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6fbb4ac2d9fd7aa987c3510309ea3c80004a968d063c42f0d34fea070817c1" +checksum = "d1daacee059634081dee4250d2814763a365b92dfe14bfdef964bc27835209d4" dependencies = [ "ammonia", "anyhow", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index a0b220c3557d..10fde31306df 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -15,6 +15,6 @@ mdbook-i18n-helpers = "0.3.3" mdbook-spec = { path = "../../doc/reference/mdbook-spec" } [dependencies.mdbook] -version = "0.4.48" +version = "0.4.49" default-features = false features = ["search"] From a3d5562fcf7f67491d55588ac3279bfade9dadcd Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 22 Apr 2025 16:30:48 +1000 Subject: [PATCH 180/262] bootstrap: Add check/test/run steps for src/tools/coverage-dump This also causes the coverage-dump unit tests to run in CI and `./x test` by default. --- src/bootstrap/src/core/build_steps/check.rs | 67 +++++++++++++++++++++ src/bootstrap/src/core/build_steps/run.rs | 28 +++++++++ src/bootstrap/src/core/build_steps/test.rs | 1 + src/bootstrap/src/core/builder/mod.rs | 2 + src/tools/coverage-dump/src/parser/tests.rs | 4 -- 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index ae9511b78674..fa848c492b4d 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -527,3 +527,70 @@ tool_check_step!(Bootstrap { path: "src/bootstrap", default: false }); // `run-make-support` will be built as part of suitable run-make compiletest test steps, but support // check to make it easier to work on. tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", default: false }); + +/// Check step for the `coverage-dump` bootstrap tool. The coverage-dump tool +/// is used internally by coverage tests. +/// +/// FIXME(Zalathar): This is temporarily separate from the other tool check +/// steps so that it can use the stage 0 compiler instead of `top_stage`, +/// without introducing conflicts with the stage 0 redesign (#119899). +/// +/// After the stage 0 redesign lands, we can look into using the stage 0 +/// compiler to check all bootstrap tools (#139170). +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) struct CoverageDump; + +impl CoverageDump { + const PATH: &str = "src/tools/coverage-dump"; +} + +impl Step for CoverageDump { + type Output = (); + + /// Most contributors won't care about coverage-dump, so don't make their + /// check builds slower unless they opt in and check it explicitly. + const DEFAULT: bool = false; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path(Self::PATH) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Self {}); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + // Make sure we haven't forgotten any fields, if there are any. + let Self {} = self; + let display_name = "coverage-dump"; + let host = builder.config.build; + let target = host; + let mode = Mode::ToolBootstrap; + + let compiler = builder.compiler(0, host); + let cargo = prepare_tool_cargo( + builder, + compiler, + mode, + target, + builder.kind, + Self::PATH, + SourceType::InTree, + &[], + ); + + let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target)) + .with_prefix(&format!("{display_name}-check")); + + let _guard = builder.msg_tool( + builder.kind, + mode, + display_name, + compiler.stage, + &compiler.host, + &target, + ); + run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + } +} diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 5cacd5b99147..7ff385052940 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -392,3 +392,31 @@ impl Step for CyclicStep { builder.ensure(CyclicStep { n: self.n.saturating_sub(1) }) } } + +/// Step to manually run the coverage-dump tool (`./x run coverage-dump`). +/// +/// The coverage-dump tool is an internal detail of coverage tests, so this run +/// step is only needed when testing coverage-dump manually. +#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +pub struct CoverageDump; + +impl Step for CoverageDump { + type Output = (); + + const DEFAULT: bool = false; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/coverage-dump") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Self {}); + } + + fn run(self, builder: &Builder<'_>) { + let mut cmd = builder.tool_cmd(Tool::CoverageDump); + cmd.args(&builder.config.free_args); + cmd.run(builder); + } +} diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a7a3b5a878c3..29fb576f5740 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -54,6 +54,7 @@ impl Step for CrateBootstrap { run.path("src/tools/jsondoclint") .path("src/tools/suggest-tests") .path("src/tools/replace-version-placeholder") + .path("src/tools/coverage-dump") // We want `./x test tidy` to _run_ the tidy tool, not its tests. // So we need a separate alias to test the tidy tool itself. .alias("tidyselftest") diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 6469bb5f2722..15dc3380a39a 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -961,6 +961,7 @@ impl<'a> Builder<'a> { check::RunMakeSupport, check::Compiletest, check::FeaturesStatusDump, + check::CoverageDump, ), Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, @@ -1114,6 +1115,7 @@ impl<'a> Builder<'a> { run::UnicodeTableGenerator, run::FeaturesStatusDump, run::CyclicStep, + run::CoverageDump, ), Kind::Setup => { describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor) diff --git a/src/tools/coverage-dump/src/parser/tests.rs b/src/tools/coverage-dump/src/parser/tests.rs index a673606b9c4c..506b0a6200bb 100644 --- a/src/tools/coverage-dump/src/parser/tests.rs +++ b/src/tools/coverage-dump/src/parser/tests.rs @@ -1,9 +1,5 @@ use super::unescape_llvm_string_contents; -// WARNING: These tests don't necessarily run in CI, and were mainly used to -// help track down problems when originally developing this tool. -// (The tool is still tested indirectly by snapshot tests that rely on it.) - // Tests for `unescape_llvm_string_contents`: #[test] From 89319f2e128379a96943de2be347ec09a80abca4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 23 Apr 2025 17:36:01 +1000 Subject: [PATCH 181/262] coverage-dump: Extract some common code to an `llvm_utils` submodule --- src/tools/coverage-dump/src/covfun.rs | 3 +- src/tools/coverage-dump/src/llvm_utils.rs | 46 +++++++++++++++++++ .../src/{parser => llvm_utils}/tests.rs | 0 src/tools/coverage-dump/src/main.rs | 1 + src/tools/coverage-dump/src/parser.rs | 34 -------------- src/tools/coverage-dump/src/prf_names.rs | 15 +----- 6 files changed, 51 insertions(+), 48 deletions(-) create mode 100644 src/tools/coverage-dump/src/llvm_utils.rs rename src/tools/coverage-dump/src/{parser => llvm_utils}/tests.rs (100%) diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs index 82ebd33d0d1c..458fd680429a 100644 --- a/src/tools/coverage-dump/src/covfun.rs +++ b/src/tools/coverage-dump/src/covfun.rs @@ -5,7 +5,8 @@ use std::sync::OnceLock; use anyhow::{Context, anyhow}; use regex::Regex; -use crate::parser::{Parser, unescape_llvm_string_contents}; +use crate::llvm_utils::unescape_llvm_string_contents; +use crate::parser::Parser; pub(crate) fn dump_covfun_mappings( llvm_ir: &str, diff --git a/src/tools/coverage-dump/src/llvm_utils.rs b/src/tools/coverage-dump/src/llvm_utils.rs new file mode 100644 index 000000000000..017fdbec0fc2 --- /dev/null +++ b/src/tools/coverage-dump/src/llvm_utils.rs @@ -0,0 +1,46 @@ +use std::sync::OnceLock; + +use regex::bytes; + +#[cfg(test)] +mod tests; + +/// Given the raw contents of a string literal in LLVM IR assembly, decodes any +/// backslash escapes and returns a vector containing the resulting byte string. +pub(crate) fn unescape_llvm_string_contents(contents: &str) -> Vec { + let escape_re = { + static RE: OnceLock = OnceLock::new(); + // LLVM IR supports two string escapes: `\\` and `\xx`. + RE.get_or_init(|| bytes::Regex::new(r"\\\\|\\([0-9A-Za-z]{2})").unwrap()) + }; + + fn u8_from_hex_digits(digits: &[u8]) -> u8 { + // We know that the input contains exactly 2 hex digits, so these calls + // should never fail. + assert_eq!(digits.len(), 2); + let digits = std::str::from_utf8(digits).unwrap(); + u8::from_str_radix(digits, 16).unwrap() + } + + escape_re + .replace_all(contents.as_bytes(), |captures: &bytes::Captures<'_>| { + let byte = match captures.get(1) { + None => b'\\', + Some(hex_digits) => u8_from_hex_digits(hex_digits.as_bytes()), + }; + [byte] + }) + .into_owned() +} + +/// LLVM's profiler/coverage metadata often uses an MD5 hash truncated to +/// 64 bits as a way to associate data stored in different tables/sections. +pub(crate) fn truncated_md5(bytes: &[u8]) -> u64 { + use md5::{Digest, Md5}; + let mut hasher = Md5::new(); + hasher.update(bytes); + let hash: [u8; 8] = hasher.finalize().as_slice()[..8].try_into().unwrap(); + // The truncated hash is explicitly little-endian, regardless of host + // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.) + u64::from_le_bytes(hash) +} diff --git a/src/tools/coverage-dump/src/parser/tests.rs b/src/tools/coverage-dump/src/llvm_utils/tests.rs similarity index 100% rename from src/tools/coverage-dump/src/parser/tests.rs rename to src/tools/coverage-dump/src/llvm_utils/tests.rs diff --git a/src/tools/coverage-dump/src/main.rs b/src/tools/coverage-dump/src/main.rs index b21e3e292f2b..6408b97a06fd 100644 --- a/src/tools/coverage-dump/src/main.rs +++ b/src/tools/coverage-dump/src/main.rs @@ -1,4 +1,5 @@ mod covfun; +mod llvm_utils; mod parser; mod prf_names; diff --git a/src/tools/coverage-dump/src/parser.rs b/src/tools/coverage-dump/src/parser.rs index 0bd4abdae3ef..f26a57b43b33 100644 --- a/src/tools/coverage-dump/src/parser.rs +++ b/src/tools/coverage-dump/src/parser.rs @@ -1,38 +1,4 @@ -#[cfg(test)] -mod tests; - -use std::sync::OnceLock; - use anyhow::ensure; -use regex::bytes; - -/// Given the raw contents of a string literal in LLVM IR assembly, decodes any -/// backslash escapes and returns a vector containing the resulting byte string. -pub(crate) fn unescape_llvm_string_contents(contents: &str) -> Vec { - let escape_re = { - static RE: OnceLock = OnceLock::new(); - // LLVM IR supports two string escapes: `\\` and `\xx`. - RE.get_or_init(|| bytes::Regex::new(r"\\\\|\\([0-9A-Za-z]{2})").unwrap()) - }; - - fn u8_from_hex_digits(digits: &[u8]) -> u8 { - // We know that the input contains exactly 2 hex digits, so these calls - // should never fail. - assert_eq!(digits.len(), 2); - let digits = std::str::from_utf8(digits).unwrap(); - u8::from_str_radix(digits, 16).unwrap() - } - - escape_re - .replace_all(contents.as_bytes(), |captures: &bytes::Captures<'_>| { - let byte = match captures.get(1) { - None => b'\\', - Some(hex_digits) => u8_from_hex_digits(hex_digits.as_bytes()), - }; - [byte] - }) - .into_owned() -} pub(crate) struct Parser<'a> { rest: &'a [u8], diff --git a/src/tools/coverage-dump/src/prf_names.rs b/src/tools/coverage-dump/src/prf_names.rs index 96d097c79a31..fe193efd8e5f 100644 --- a/src/tools/coverage-dump/src/prf_names.rs +++ b/src/tools/coverage-dump/src/prf_names.rs @@ -4,7 +4,8 @@ use std::sync::OnceLock; use anyhow::{anyhow, ensure}; use regex::Regex; -use crate::parser::{Parser, unescape_llvm_string_contents}; +use crate::llvm_utils::{truncated_md5, unescape_llvm_string_contents}; +use crate::parser::Parser; /// Scans through the contents of an LLVM IR assembly file to find `__llvm_prf_names` /// entries, decodes them, and creates a table that maps name hash values to @@ -25,18 +26,6 @@ pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result u64 { - use md5::{Digest, Md5}; - let mut hasher = Md5::new(); - hasher.update(bytes); - let hash: [u8; 8] = hasher.finalize().as_slice()[..8].try_into().unwrap(); - // The truncated hash is explicitly little-endian, regardless of host - // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.) - u64::from_le_bytes(hash) - } - fn demangle_if_able(symbol_name_bytes: &[u8]) -> anyhow::Result { // In practice, raw symbol names should always be ASCII. let symbol_name_str = std::str::from_utf8(symbol_name_bytes)?; From bc3f0e326a5ef77bb4e3531db5190109d8e2420b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 23 Apr 2025 17:47:01 +1000 Subject: [PATCH 182/262] coverage-dump: Extract a common parser method for maybe-compressed bytes --- src/tools/coverage-dump/src/llvm_utils.rs | 39 +++++++++++++++++++++++ src/tools/coverage-dump/src/prf_names.rs | 25 ++------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/tools/coverage-dump/src/llvm_utils.rs b/src/tools/coverage-dump/src/llvm_utils.rs index 017fdbec0fc2..92322b256a82 100644 --- a/src/tools/coverage-dump/src/llvm_utils.rs +++ b/src/tools/coverage-dump/src/llvm_utils.rs @@ -1,7 +1,11 @@ +use std::borrow::Cow; use std::sync::OnceLock; +use anyhow::{anyhow, ensure}; use regex::bytes; +use crate::parser::Parser; + #[cfg(test)] mod tests; @@ -44,3 +48,38 @@ pub(crate) fn truncated_md5(bytes: &[u8]) -> u64 { // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.) u64::from_le_bytes(hash) } + +impl<'a> Parser<'a> { + /// Reads a sequence of: + /// - Length of uncompressed data in bytes, as ULEB128 + /// - Length of compressed data in bytes (or 0), as ULEB128 + /// - The indicated number of compressed or uncompressed bytes + /// + /// If the number of compressed bytes is 0, the subsequent bytes are + /// uncompressed. Otherwise, the subsequent bytes are compressed, and will + /// be decompressed. + /// + /// Returns the uncompressed bytes that were read directly or decompressed. + pub(crate) fn read_chunk_to_uncompressed_bytes(&mut self) -> anyhow::Result> { + let uncompressed_len = self.read_uleb128_usize()?; + let compressed_len = self.read_uleb128_usize()?; + + if compressed_len == 0 { + // The bytes are uncompressed, so read them directly. + let uncompressed_bytes = self.read_n_bytes(uncompressed_len)?; + Ok(Cow::Borrowed(uncompressed_bytes)) + } else { + // The bytes are compressed, so read and decompress them. + let compressed_bytes = self.read_n_bytes(compressed_len)?; + + let uncompressed_bytes = miniz_oxide::inflate::decompress_to_vec_zlib_with_limit( + compressed_bytes, + uncompressed_len, + ) + .map_err(|e| anyhow!("{e:?}"))?; + ensure!(uncompressed_bytes.len() == uncompressed_len); + + Ok(Cow::Owned(uncompressed_bytes)) + } + } +} diff --git a/src/tools/coverage-dump/src/prf_names.rs b/src/tools/coverage-dump/src/prf_names.rs index fe193efd8e5f..f9ab35deba50 100644 --- a/src/tools/coverage-dump/src/prf_names.rs +++ b/src/tools/coverage-dump/src/prf_names.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::sync::OnceLock; -use anyhow::{anyhow, ensure}; use regex::Regex; use crate::llvm_utils::{truncated_md5, unescape_llvm_string_contents}; @@ -43,26 +42,8 @@ pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result anyhow::Result Date: Tue, 22 Apr 2025 21:49:57 +1000 Subject: [PATCH 183/262] coverage-dump: Include filenames hash in covfun line data --- Cargo.lock | 1 + src/tools/coverage-dump/Cargo.toml | 1 + src/tools/coverage-dump/src/covfun.rs | 73 +++++++++++++-------- src/tools/coverage-dump/src/covfun/tests.rs | 53 +++++++++++++++ 4 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 src/tools/coverage-dump/src/covfun/tests.rs diff --git a/Cargo.lock b/Cargo.lock index bbd3f33d7bd3..b5fc86f50fe4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,6 +777,7 @@ name = "coverage-dump" version = "0.1.0" dependencies = [ "anyhow", + "itertools", "leb128", "md-5", "miniz_oxide 0.7.4", diff --git a/src/tools/coverage-dump/Cargo.toml b/src/tools/coverage-dump/Cargo.toml index 7f14286b5d0c..6f92ac50d963 100644 --- a/src/tools/coverage-dump/Cargo.toml +++ b/src/tools/coverage-dump/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.71" +itertools = "0.12" leb128 = "0.2.5" md5 = { package = "md-5" , version = "0.10.5" } miniz_oxide = "0.7.1" diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs index 458fd680429a..4c0ce2058225 100644 --- a/src/tools/coverage-dump/src/covfun.rs +++ b/src/tools/coverage-dump/src/covfun.rs @@ -1,13 +1,17 @@ use std::collections::HashMap; use std::fmt::{self, Debug, Write as _}; -use std::sync::OnceLock; +use std::sync::LazyLock; -use anyhow::{Context, anyhow}; +use anyhow::{Context, anyhow, ensure}; +use itertools::Itertools; use regex::Regex; use crate::llvm_utils::unescape_llvm_string_contents; use crate::parser::Parser; +#[cfg(test)] +mod tests; + pub(crate) fn dump_covfun_mappings( llvm_ir: &str, function_names: &HashMap, @@ -16,9 +20,12 @@ pub(crate) fn dump_covfun_mappings( // each entry with its (demangled) name. let mut covfun_entries = llvm_ir .lines() - .filter_map(covfun_line_data) - .map(|line_data| (function_names.get(&line_data.name_hash).map(String::as_str), line_data)) - .collect::>(); + .filter(|line| is_covfun_line(line)) + .map(parse_covfun_line) + .map_ok(|line_data| { + (function_names.get(&line_data.name_hash).map(String::as_str), line_data) + }) + .collect::, _>>()?; covfun_entries.sort_by(|a, b| { // Sort entries primarily by name, to help make the order consistent // across platforms and relatively insensitive to changes. @@ -108,36 +115,50 @@ pub(crate) fn dump_covfun_mappings( Ok(()) } +#[derive(Debug, PartialEq, Eq)] struct CovfunLineData { - name_hash: u64, is_used: bool, + name_hash: u64, + filenames_hash: u64, payload: Vec, } -/// Checks a line of LLVM IR assembly to see if it contains an `__llvm_covfun` -/// entry, and if so extracts relevant data in a `CovfunLineData`. -fn covfun_line_data(line: &str) -> Option { - let re = { - // We cheat a little bit and match variable names `@__covrec_[HASH]u` - // rather than the section name, because the section name is harder to - // extract and differs across Linux/Windows/macOS. We also extract the - // symbol name hash from the variable name rather than the data, since - // it's easier and both should match. - static RE: OnceLock = OnceLock::new(); - RE.get_or_init(|| { - Regex::new( - r#"^@__covrec_(?[0-9A-Z]+)(?u)? = .*\[[0-9]+ x i8\] c"(?[^"]*)".*$"#, - ) - .unwrap() - }) - }; +fn is_covfun_line(line: &str) -> bool { + line.starts_with("@__covrec_") +} - let captures = re.captures(line)?; - let name_hash = u64::from_str_radix(&captures["name_hash"], 16).unwrap(); +/// Given a line of LLVM IR assembly that should contain an `__llvm_covfun` +/// entry, parses it to extract relevant data in a `CovfunLineData`. +fn parse_covfun_line(line: &str) -> anyhow::Result { + ensure!(is_covfun_line(line)); + + // We cheat a little bit and match variable names `@__covrec_[HASH]u` + // rather than the section name, because the section name is harder to + // extract and differs across Linux/Windows/macOS. + const RE_STRING: &str = r#"(?x)^ + @__covrec_[0-9A-Z]+(?u)? + \ = \ # (trailing space) + .* + <\{ + \ i64 \ (? -? [0-9]+), + \ i32 \ -? [0-9]+, # (length of payload; currently unused) + \ i64 \ -? [0-9]+, # (source hash; currently unused) + \ i64 \ (? -? [0-9]+), + \ \[ [0-9]+ \ x \ i8 \] \ c"(?[^"]*)" + \ # (trailing space) + }> + .*$ + "#; + static RE: LazyLock = LazyLock::new(|| Regex::new(RE_STRING).unwrap()); + + let captures = + RE.captures(line).with_context(|| format!("couldn't parse covfun line: {line:?}"))?; let is_used = captures.name("is_used").is_some(); + let name_hash = i64::from_str_radix(&captures["name_hash"], 10).unwrap() as u64; + let filenames_hash = i64::from_str_radix(&captures["filenames_hash"], 10).unwrap() as u64; let payload = unescape_llvm_string_contents(&captures["payload"]); - Some(CovfunLineData { name_hash, is_used, payload }) + Ok(CovfunLineData { is_used, name_hash, filenames_hash, payload }) } // Extra parser methods only needed when parsing `covfun` payloads. diff --git a/src/tools/coverage-dump/src/covfun/tests.rs b/src/tools/coverage-dump/src/covfun/tests.rs new file mode 100644 index 000000000000..1ce833784bd4 --- /dev/null +++ b/src/tools/coverage-dump/src/covfun/tests.rs @@ -0,0 +1,53 @@ +use super::{CovfunLineData, parse_covfun_line}; + +/// Integers in LLVM IR are not inherently signed/unsigned, and the text format tends +/// to emit them in signed form, so this helper function converts `i64` to `u64`. +fn as_u64(x: i64) -> u64 { + x as u64 +} + +#[test] +fn parse_covfun_line_data() { + struct Case { + line: &'static str, + expected: CovfunLineData, + } + let cases = &[ + // Copied from `trivial.ll`: + Case { + line: r#"@__covrec_49A9BAAE5F896E81u = linkonce_odr hidden constant <{ i64, i32, i64, i64, [9 x i8] }> <{ i64 5307978893922758273, i32 9, i64 445092354169400020, i64 6343436898695299756, [9 x i8] c"\01\01\00\01\01\03\01\00\0D" }>, section "__LLVM_COV,__llvm_covfun", align 8"#, + expected: CovfunLineData { + is_used: true, + name_hash: as_u64(5307978893922758273), + filenames_hash: as_u64(6343436898695299756), + payload: b"\x01\x01\x00\x01\x01\x03\x01\x00\x0D".to_vec(), + }, + }, + // Copied from `on-off-sandwich.ll`: + Case { + line: r#"@__covrec_D0CE53C5E64F319Au = linkonce_odr hidden constant <{ i64, i32, i64, i64, [14 x i8] }> <{ i64 -3400688559180533350, i32 14, i64 7307957714577672185, i64 892196767019953100, [14 x i8] c"\01\01\00\02\01\10\05\02\10\01\07\05\00\06" }>, section "__LLVM_COV,__llvm_covfun", align 8"#, + expected: CovfunLineData { + is_used: true, + name_hash: as_u64(-3400688559180533350), + filenames_hash: as_u64(892196767019953100), + payload: b"\x01\x01\x00\x02\x01\x10\x05\x02\x10\x01\x07\x05\x00\x06".to_vec(), + }, + }, + // Copied from `no-core.ll`: + Case { + line: r#"@__covrec_F8016FC82D46106u = linkonce_odr hidden constant <{ i64, i32, i64, i64, [9 x i8] }> <{ i64 1116917981370409222, i32 9, i64 -8857254680411629915, i64 -3625186110715410276, [9 x i8] c"\01\01\00\01\01\0C\01\00\0D" }>, section "__LLVM_COV,__llvm_covfun", align 8"#, + expected: CovfunLineData { + is_used: true, + name_hash: as_u64(1116917981370409222), + filenames_hash: as_u64(-3625186110715410276), + payload: b"\x01\x01\x00\x01\x01\x0C\x01\x00\x0D".to_vec(), + }, + }, + ]; + + for &Case { line, ref expected } in cases { + println!("- {line}"); + let line_data = parse_covfun_line(line).map_err(|e| e.to_string()); + assert_eq!(line_data.as_ref(), Ok(expected)); + } +} From 041b2b2c982edb6e36a7d80081d040dbaf388a2b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 24 Apr 2025 13:47:13 +1000 Subject: [PATCH 184/262] coverage-dump: Make filenames available to covfun record dumping Actually printing the filenames is deferred to a subsequent commit that will simultaneously bless all affected tests. --- src/tools/coverage-dump/src/covfun.rs | 11 +++- src/tools/coverage-dump/src/covmap.rs | 75 +++++++++++++++++++++++++++ src/tools/coverage-dump/src/main.rs | 4 +- 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 src/tools/coverage-dump/src/covmap.rs diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs index 4c0ce2058225..d3744d3bf807 100644 --- a/src/tools/coverage-dump/src/covfun.rs +++ b/src/tools/coverage-dump/src/covfun.rs @@ -2,10 +2,11 @@ use std::collections::HashMap; use std::fmt::{self, Debug, Write as _}; use std::sync::LazyLock; -use anyhow::{Context, anyhow, ensure}; +use anyhow::{Context, anyhow, bail, ensure}; use itertools::Itertools; use regex::Regex; +use crate::covmap::FilenameTables; use crate::llvm_utils::unescape_llvm_string_contents; use crate::parser::Parser; @@ -14,6 +15,7 @@ mod tests; pub(crate) fn dump_covfun_mappings( llvm_ir: &str, + filename_tables: &FilenameTables, function_names: &HashMap, ) -> anyhow::Result<()> { // Extract function coverage entries from the LLVM IR assembly, and associate @@ -49,7 +51,12 @@ pub(crate) fn dump_covfun_mappings( println!("Number of files: {num_files}"); for i in 0..num_files { - let global_file_id = parser.read_uleb128_u32()?; + let global_file_id = parser.read_uleb128_usize()?; + let &CovfunLineData { filenames_hash, .. } = line_data; + #[expect(unused)] // Removed later in this PR. + let Some(filename) = filename_tables.lookup(filenames_hash, global_file_id) else { + bail!("couldn't resolve global file: {filenames_hash}, {global_file_id}"); + }; println!("- file {i} => global file {global_file_id}"); } diff --git a/src/tools/coverage-dump/src/covmap.rs b/src/tools/coverage-dump/src/covmap.rs new file mode 100644 index 000000000000..2246ca2d5757 --- /dev/null +++ b/src/tools/coverage-dump/src/covmap.rs @@ -0,0 +1,75 @@ +use std::collections::HashMap; +use std::sync::LazyLock; + +use anyhow::{Context, ensure}; +use regex::Regex; + +use crate::llvm_utils::{truncated_md5, unescape_llvm_string_contents}; +use crate::parser::Parser; + +#[derive(Debug, Default)] +pub(crate) struct FilenameTables { + map: HashMap>, +} + +impl FilenameTables { + pub(crate) fn lookup(&self, filenames_hash: u64, global_file_id: usize) -> Option<&str> { + let table = self.map.get(&filenames_hash)?; + let filename = table.get(global_file_id)?; + Some(filename) + } +} + +struct CovmapLineData { + payload: Vec, +} + +pub(crate) fn make_filename_tables(llvm_ir: &str) -> anyhow::Result { + let mut map = HashMap::default(); + + for line in llvm_ir.lines().filter(|line| is_covmap_line(line)) { + let CovmapLineData { payload } = parse_covmap_line(line)?; + + let mut parser = Parser::new(&payload); + let n_filenames = parser.read_uleb128_usize()?; + let uncompressed_bytes = parser.read_chunk_to_uncompressed_bytes()?; + parser.ensure_empty()?; + + let mut filenames_table = vec![]; + + let mut parser = Parser::new(&uncompressed_bytes); + for _ in 0..n_filenames { + let len = parser.read_uleb128_usize()?; + let bytes = parser.read_n_bytes(len)?; + let filename = str::from_utf8(bytes)?; + filenames_table.push(filename.to_owned()); + } + + let filenames_hash = truncated_md5(&payload); + map.insert(filenames_hash, filenames_table); + } + + Ok(FilenameTables { map }) +} + +fn is_covmap_line(line: &str) -> bool { + line.starts_with("@__llvm_coverage_mapping ") +} + +fn parse_covmap_line(line: &str) -> anyhow::Result { + ensure!(is_covmap_line(line)); + + const RE_STRING: &str = r#"(?x)^ + @__llvm_coverage_mapping \ = + .* + \[ [0-9]+ \ x \ i8 \] \ c"(?[^"]*)" + .*$ + "#; + static RE: LazyLock = LazyLock::new(|| Regex::new(RE_STRING).unwrap()); + + let captures = + RE.captures(line).with_context(|| format!("couldn't parse covmap line: {line:?}"))?; + let payload = unescape_llvm_string_contents(&captures["payload"]); + + Ok(CovmapLineData { payload }) +} diff --git a/src/tools/coverage-dump/src/main.rs b/src/tools/coverage-dump/src/main.rs index 6408b97a06fd..2c76d2f24602 100644 --- a/src/tools/coverage-dump/src/main.rs +++ b/src/tools/coverage-dump/src/main.rs @@ -1,4 +1,5 @@ mod covfun; +mod covmap; mod llvm_utils; mod parser; mod prf_names; @@ -18,8 +19,9 @@ fn main() -> anyhow::Result<()> { let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?; let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?; + let filename_tables = covmap::make_filename_tables(&llvm_ir)?; let function_names = crate::prf_names::make_function_names_table(&llvm_ir)?; - crate::covfun::dump_covfun_mappings(&llvm_ir, &function_names)?; + crate::covfun::dump_covfun_mappings(&llvm_ir, &filename_tables, &function_names)?; Ok(()) } From c53a76743c01afa356ae5301bc1b35044354da7a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 24 Apr 2025 17:36:50 +1000 Subject: [PATCH 185/262] coverage-dump: Dump filenames instead of global file IDs (and bless) --- src/tools/coverage-dump/src/covfun.rs | 3 +- tests/coverage/abort.cov-map | 4 +- tests/coverage/assert-ne.cov-map | 2 +- tests/coverage/assert.cov-map | 4 +- tests/coverage/assert_not.cov-map | 2 +- tests/coverage/async.cov-map | 50 +++++++++---------- tests/coverage/async2.cov-map | 12 ++--- tests/coverage/async_block.cov-map | 4 +- tests/coverage/async_closure.cov-map | 12 ++--- tests/coverage/attr/impl.cov-map | 6 +-- tests/coverage/attr/module.cov-map | 6 +-- tests/coverage/attr/nested.cov-map | 4 +- tests/coverage/attr/off-on-sandwich.cov-map | 6 +-- .../coverage/attr/trait-impl-inherit.cov-map | 2 +- tests/coverage/await_ready.cov-map | 4 +- tests/coverage/bad_counter_ids.cov-map | 16 +++--- tests/coverage/bench.cov-map | 2 +- tests/coverage/branch/generics.cov-map | 6 +-- tests/coverage/branch/guard.cov-map | 2 +- tests/coverage/branch/if-let.cov-map | 4 +- tests/coverage/branch/if.cov-map | 8 +-- tests/coverage/branch/lazy-boolean.cov-map | 8 +-- tests/coverage/branch/let-else.cov-map | 2 +- tests/coverage/branch/match-arms.cov-map | 6 +-- tests/coverage/branch/match-trivial.cov-map | 4 +- tests/coverage/branch/no-mir-spans.cov-map | 8 +-- tests/coverage/branch/while.cov-map | 8 +-- tests/coverage/closure.cov-map | 42 ++++++++-------- tests/coverage/closure_bug.cov-map | 10 ++-- tests/coverage/closure_macro.cov-map | 6 +-- tests/coverage/closure_macro_async.cov-map | 8 +-- tests/coverage/closure_unit_return.cov-map | 8 +-- tests/coverage/condition/conditions.cov-map | 14 +++--- tests/coverage/conditions.cov-map | 2 +- tests/coverage/continue.cov-map | 2 +- tests/coverage/coroutine.cov-map | 6 +-- tests/coverage/coverage_attr_closure.cov-map | 8 +-- tests/coverage/dead_code.cov-map | 6 +-- tests/coverage/drop_trait.cov-map | 4 +- tests/coverage/fn_sig_into_try.cov-map | 8 +-- tests/coverage/generic-unused-impl.cov-map | 4 +- tests/coverage/generics.cov-map | 10 ++-- tests/coverage/holes.cov-map | 10 ++-- tests/coverage/if.cov-map | 2 +- tests/coverage/if_else.cov-map | 2 +- tests/coverage/if_not.cov-map | 2 +- tests/coverage/ignore_run.cov-map | 2 +- tests/coverage/inline-dead.cov-map | 8 +-- tests/coverage/inline.cov-map | 14 +++--- tests/coverage/inner_items.cov-map | 8 +-- tests/coverage/issue-83601.cov-map | 2 +- tests/coverage/issue-84561.cov-map | 12 ++--- tests/coverage/issue-85461.cov-map | 2 +- tests/coverage/issue-93054.cov-map | 6 +-- tests/coverage/lazy_boolean.cov-map | 2 +- tests/coverage/let_else_loop.cov-map | 6 +-- tests/coverage/long_and_wide.cov-map | 8 +-- tests/coverage/loop-break.cov-map | 2 +- tests/coverage/loop_break_value.cov-map | 2 +- tests/coverage/loops_branches.cov-map | 6 +-- tests/coverage/macro_in_closure.cov-map | 4 +- tests/coverage/macro_name_span.cov-map | 4 +- tests/coverage/match_or_pattern.cov-map | 2 +- tests/coverage/mcdc/condition-limit.cov-map | 2 +- tests/coverage/mcdc/if.cov-map | 14 +++--- .../coverage/mcdc/inlined_expressions.cov-map | 2 +- tests/coverage/mcdc/nested_if.cov-map | 8 +-- tests/coverage/mcdc/non_control_flow.cov-map | 14 +++--- tests/coverage/nested_loops.cov-map | 2 +- tests/coverage/no-core.cov-map | 2 +- tests/coverage/no_cov_crate.cov-map | 14 +++--- tests/coverage/no_spans.cov-map | 4 +- tests/coverage/no_spans_if_not.cov-map | 4 +- tests/coverage/overflow.cov-map | 4 +- tests/coverage/panic_unwind.cov-map | 4 +- tests/coverage/partial_eq.cov-map | 4 +- tests/coverage/simple_loop.cov-map | 2 +- tests/coverage/simple_match.cov-map | 2 +- tests/coverage/sort_groups.cov-map | 12 ++--- tests/coverage/test_harness.cov-map | 4 +- tests/coverage/tight_inf_loop.cov-map | 2 +- tests/coverage/trivial.cov-map | 2 +- tests/coverage/try_error_result.cov-map | 12 ++--- tests/coverage/unicode.cov-map | 6 +-- tests/coverage/unreachable.cov-map | 6 +-- tests/coverage/unused.cov-map | 14 +++--- tests/coverage/unused_mod.cov-map | 4 +- tests/coverage/uses_crate.cov-map | 10 ++-- tests/coverage/uses_inline_crate.cov-map | 12 ++--- tests/coverage/while.cov-map | 2 +- tests/coverage/while_early_ret.cov-map | 2 +- tests/coverage/yield.cov-map | 6 +-- 92 files changed, 307 insertions(+), 308 deletions(-) diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs index d3744d3bf807..1cc9f4dc5d6a 100644 --- a/src/tools/coverage-dump/src/covfun.rs +++ b/src/tools/coverage-dump/src/covfun.rs @@ -53,11 +53,10 @@ pub(crate) fn dump_covfun_mappings( for i in 0..num_files { let global_file_id = parser.read_uleb128_usize()?; let &CovfunLineData { filenames_hash, .. } = line_data; - #[expect(unused)] // Removed later in this PR. let Some(filename) = filename_tables.lookup(filenames_hash, global_file_id) else { bail!("couldn't resolve global file: {filenames_hash}, {global_file_id}"); }; - println!("- file {i} => global file {global_file_id}"); + println!("- file {i} => {filename}"); } let num_expressions = parser.read_uleb128_u32()?; diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map index 26536caeba52..4021537392b9 100644 --- a/tests/coverage/abort.cov-map +++ b/tests/coverage/abort.cov-map @@ -1,7 +1,7 @@ Function name: abort::main Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/abort.rs Number of expressions: 7 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) @@ -36,7 +36,7 @@ Highest counter ID seen: c4 Function name: abort::might_abort Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/abort.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map index 27d4b0382dec..4bee7d7b97c7 100644 --- a/tests/coverage/assert-ne.cov-map +++ b/tests/coverage/assert-ne.cov-map @@ -1,7 +1,7 @@ Function name: assert_ne::main Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/assert-ne.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map index 903cccfe9cbc..e7ee91979711 100644 --- a/tests/coverage/assert.cov-map +++ b/tests/coverage/assert.cov-map @@ -1,7 +1,7 @@ Function name: assert::main Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/assert.rs Number of expressions: 6 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add) @@ -28,7 +28,7 @@ Highest counter ID seen: c3 Function name: assert::might_fail_assert Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/assert.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map index 3aef4274edc3..d3ef867a8a82 100644 --- a/tests/coverage/assert_not.cov-map +++ b/tests/coverage/assert_not.cov-map @@ -1,7 +1,7 @@ Function name: assert_not::main Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/assert_not.rs Number of expressions: 0 Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17) diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index 521562f6b912..8d8dd2430571 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -1,7 +1,7 @@ Function name: async::c Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 1) to (start + 0, 25) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: async::c::{closure#0} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -24,7 +24,7 @@ Highest counter ID seen: c1 Function name: async::d Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) @@ -33,7 +33,7 @@ Highest counter ID seen: c0 Function name: async::d::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) @@ -42,7 +42,7 @@ Highest counter ID seen: c0 Function name: async::e (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 14] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 21, 1) to (start + 0, 20) @@ -51,7 +51,7 @@ Highest counter ID seen: (none) Function name: async::e::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 14, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 21, 20) to (start + 0, 25) @@ -60,7 +60,7 @@ Highest counter ID seen: (none) Function name: async::f Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 14] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 23, 1) to (start + 0, 20) @@ -69,7 +69,7 @@ Highest counter ID seen: c0 Function name: async::f::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 14, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 23, 20) to (start + 0, 25) @@ -78,7 +78,7 @@ Highest counter ID seen: c0 Function name: async::foo (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 25, 1) to (start + 0, 30) @@ -87,7 +87,7 @@ Highest counter ID seen: (none) Function name: async::foo::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 1e, 00, 2d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 25, 30) to (start + 0, 45) @@ -96,7 +96,7 @@ Highest counter ID seen: (none) Function name: async::g Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 27, 1) to (start + 0, 23) @@ -105,7 +105,7 @@ Highest counter ID seen: c0 Function name: async::g::{closure#0} (unused) Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1b, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 11 - Code(Zero) at (prev + 27, 23) to (start + 1, 12) @@ -124,7 +124,7 @@ Highest counter ID seen: (none) Function name: async::h Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 16] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 35, 1) to (start + 0, 22) @@ -133,7 +133,7 @@ Highest counter ID seen: c0 Function name: async::h::{closure#0} (unused) Raw bytes (39): 0x[01, 01, 00, 07, 00, 23, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 7 - Code(Zero) at (prev + 35, 22) to (start + 3, 12) @@ -148,7 +148,7 @@ Highest counter ID seen: (none) Function name: async::i Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 13] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 44, 1) to (start + 0, 19) @@ -157,7 +157,7 @@ Highest counter ID seen: c0 Function name: async::i::{closure#0} Raw bytes (65): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(4), rhs = Counter(5) @@ -182,7 +182,7 @@ Highest counter ID seen: c5 Function name: async::j Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) @@ -205,7 +205,7 @@ Highest counter ID seen: c2 Function name: async::j::c Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -219,7 +219,7 @@ Highest counter ID seen: c1 Function name: async::j::d Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23) @@ -228,7 +228,7 @@ Highest counter ID seen: c0 Function name: async::j::f Raw bytes (9): 0x[01, 01, 00, 01, 01, 41, 05, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 65, 5) to (start + 0, 23) @@ -237,7 +237,7 @@ Highest counter ID seen: c0 Function name: async::k (unused) Raw bytes (29): 0x[01, 01, 00, 05, 00, 49, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 5 - Code(Zero) at (prev + 73, 1) to (start + 1, 12) @@ -250,7 +250,7 @@ Highest counter ID seen: (none) Function name: async::l Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 51, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -266,7 +266,7 @@ Highest counter ID seen: c2 Function name: async::m Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 89, 1) to (start + 0, 25) @@ -275,7 +275,7 @@ Highest counter ID seen: c0 Function name: async::m::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 59, 19, 00, 22] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 89, 25) to (start + 0, 34) @@ -284,7 +284,7 @@ Highest counter ID seen: (none) Function name: async::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 08, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 91, 1) to (start + 8, 2) diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map index c2a0645ee9a8..43ec9f397bd9 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -1,7 +1,7 @@ Function name: async2::async_func Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 15, 1) to (start + 0, 23) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: async2::async_func::{closure#0} Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9) @@ -22,7 +22,7 @@ Highest counter ID seen: c0 Function name: async2::async_func_just_println Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 23, 1) to (start + 0, 36) @@ -31,7 +31,7 @@ Highest counter ID seen: c0 Function name: async2::async_func_just_println::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 24, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 23, 36) to (start + 2, 2) @@ -40,7 +40,7 @@ Highest counter ID seen: c0 Function name: async2::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 07, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 27, 1) to (start + 7, 2) @@ -49,7 +49,7 @@ Highest counter ID seen: c0 Function name: async2::non_async_func Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9) diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map index d9196f446f13..9e76bb981ffe 100644 --- a/tests/coverage/async_block.cov-map +++ b/tests/coverage/async_block.cov-map @@ -1,7 +1,7 @@ Function name: async_block::main Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 22, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_block.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 6 @@ -19,7 +19,7 @@ Highest counter ID seen: c1 Function name: async_block::main::{closure#0} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_block.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index a4ef0ceeb6df..10b6db0fc713 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -1,7 +1,7 @@ Function name: async_closure::call_once:: Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: async_closure::call_once::::{closure#0} Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 06, 2b, 01, 0e, 02, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 2 @@ -22,7 +22,7 @@ Highest counter ID seen: c0 Function name: async_closure::main Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22) @@ -32,7 +32,7 @@ Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) @@ -42,7 +42,7 @@ Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) @@ -52,7 +52,7 @@ Highest counter ID seen: c0 Function name: async_closure::main::{closure#0}::{closure#0}:: Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) diff --git a/tests/coverage/attr/impl.cov-map b/tests/coverage/attr/impl.cov-map index 8a23c082082e..ad24dfb63229 100644 --- a/tests/coverage/attr/impl.cov-map +++ b/tests/coverage/attr/impl.cov-map @@ -1,7 +1,7 @@ Function name: ::off_on (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 05, 00, 13] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/impl.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 15, 5) to (start + 0, 19) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: ::on_inherit (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/impl.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 23, 5) to (start + 0, 23) @@ -19,7 +19,7 @@ Highest counter ID seen: (none) Function name: ::on_on (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 05, 00, 12] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/impl.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 26, 5) to (start + 0, 18) diff --git a/tests/coverage/attr/module.cov-map b/tests/coverage/attr/module.cov-map index 81e20a2c2649..eba24da0dd1e 100644 --- a/tests/coverage/attr/module.cov-map +++ b/tests/coverage/attr/module.cov-map @@ -1,7 +1,7 @@ Function name: module::off::on (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 0d, 05, 00, 0f] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/module.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 13, 5) to (start + 0, 15) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: module::on::inherit (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 05, 00, 14] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/module.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 21, 5) to (start + 0, 20) @@ -19,7 +19,7 @@ Highest counter ID seen: (none) Function name: module::on::on (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 05, 00, 0f] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/module.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 24, 5) to (start + 0, 15) diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map index 138b3159ea5c..a831340bce5e 100644 --- a/tests/coverage/attr/nested.cov-map +++ b/tests/coverage/attr/nested.cov-map @@ -1,7 +1,7 @@ Function name: nested::closure_expr Raw bytes (14): 0x[01, 01, 00, 02, 01, 40, 01, 01, 0f, 01, 0b, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 64, 1) to (start + 1, 15) @@ -11,7 +11,7 @@ Highest counter ID seen: c0 Function name: nested::closure_tail Raw bytes (14): 0x[01, 01, 00, 02, 01, 4f, 01, 01, 0f, 01, 11, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 79, 1) to (start + 1, 15) diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map index c55c5897d8ba..d26f06bb81f5 100644 --- a/tests/coverage/attr/off-on-sandwich.cov-map +++ b/tests/coverage/attr/off-on-sandwich.cov-map @@ -1,7 +1,7 @@ Function name: off_on_sandwich::dense_a::dense_b Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 10, 01, 07, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 16, 5) to (start + 2, 16) @@ -11,7 +11,7 @@ Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 15, 01, 0b, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 34, 9) to (start + 2, 21) @@ -21,7 +21,7 @@ Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 19, 01, 07, 0d, 00, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 37, 13) to (start + 2, 25) diff --git a/tests/coverage/attr/trait-impl-inherit.cov-map b/tests/coverage/attr/trait-impl-inherit.cov-map index eab9f926bb77..b3e875785926 100644 --- a/tests/coverage/attr/trait-impl-inherit.cov-map +++ b/tests/coverage/attr/trait-impl-inherit.cov-map @@ -1,7 +1,7 @@ Function name: ::f Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/trait-impl-inherit.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map index 61fd4c7814d8..7bff6a4a7748 100644 --- a/tests/coverage/await_ready.cov-map +++ b/tests/coverage/await_ready.cov-map @@ -1,7 +1,7 @@ Function name: await_ready::await_ready Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/await_ready.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 30) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: await_ready::await_ready::{closure#0} Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 0e, 1e, 03, 0f, 02, 04, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/await_ready.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 2 diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map index f08a70a899d0..2ef299307261 100644 --- a/tests/coverage/bad_counter_ids.cov-map +++ b/tests/coverage/bad_counter_ids.cov-map @@ -1,7 +1,7 @@ Function name: bad_counter_ids::eq_bad Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 0f, 00, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 36, 1) to (start + 2, 15) @@ -11,7 +11,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::eq_bad_message Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15) @@ -22,7 +22,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 0f, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 16, 1) to (start + 2, 15) @@ -32,7 +32,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good_message Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15) @@ -43,7 +43,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::ne_bad Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 0f, 00, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 46, 1) to (start + 2, 15) @@ -53,7 +53,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::ne_bad_message Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15) @@ -64,7 +64,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::ne_good Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 0f, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 26, 1) to (start + 2, 15) @@ -74,7 +74,7 @@ Highest counter ID seen: c0 Function name: bad_counter_ids::ne_good_message Raw bytes (19): 0x[01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15) diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map index 9ee6510f6904..1707957fddc1 100644 --- a/tests/coverage/bench.cov-map +++ b/tests/coverage/bench.cov-map @@ -1,7 +1,7 @@ Function name: bench::my_bench Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 00, 27] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/bench.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39) diff --git a/tests/coverage/branch/generics.cov-map b/tests/coverage/branch/generics.cov-map index 656890634ff4..50e6eedb676f 100644 --- a/tests/coverage/branch/generics.cov-map +++ b/tests/coverage/branch/generics.cov-map @@ -1,7 +1,7 @@ Function name: generics::print_size::<()> Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 @@ -18,7 +18,7 @@ Highest counter ID seen: c1 Function name: generics::print_size:: Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 @@ -35,7 +35,7 @@ Highest counter ID seen: c1 Function name: generics::print_size:: Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map index 46533df00f71..c1a275b34a3f 100644 --- a/tests/coverage/branch/guard.cov-map +++ b/tests/coverage/branch/guard.cov-map @@ -1,7 +1,7 @@ Function name: guard::branch_match_guard Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 0e, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/guard.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(1), rhs = Counter(3) - expression 1 operands: lhs = Counter(2), rhs = Counter(1) diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map index 7f6b174615a9..a79232233013 100644 --- a/tests/coverage/branch/if-let.cov-map +++ b/tests/coverage/branch/if-let.cov-map @@ -1,7 +1,7 @@ Function name: if_let::if_let Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if-let.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 7 @@ -21,7 +21,7 @@ Highest counter ID seen: c1 Function name: if_let::if_let_chain Raw bytes (74): 0x[01, 01, 08, 01, 05, 01, 1f, 05, 09, 01, 1f, 05, 09, 01, 1f, 05, 09, 05, 09, 0a, 01, 17, 01, 00, 33, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 16, 09, 01, 10, 00, 17, 16, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 16, 01, 05, 03, 06, 1f, 03, 0c, 02, 06, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if-let.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add) diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map index 1d40f032aa87..64b13fcfaa1e 100644 --- a/tests/coverage/branch/if.cov-map +++ b/tests/coverage/branch/if.cov-map @@ -1,7 +1,7 @@ Function name: if::branch_and Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -25,7 +25,7 @@ Highest counter ID seen: c2 Function name: if::branch_not Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 7 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -70,7 +70,7 @@ Highest counter ID seen: c4 Function name: if::branch_not_as Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 0e, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -106,7 +106,7 @@ Highest counter ID seen: c3 Function name: if::branch_or Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add) diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map index 5d4fc57eb8f7..b01ca5c94dff 100644 --- a/tests/coverage/branch/lazy-boolean.cov-map +++ b/tests/coverage/branch/lazy-boolean.cov-map @@ -1,7 +1,7 @@ Function name: lazy_boolean::branch_and Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/lazy-boolean.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -18,7 +18,7 @@ Highest counter ID seen: c1 Function name: lazy_boolean::branch_or Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/lazy-boolean.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -36,7 +36,7 @@ Highest counter ID seen: c1 Function name: lazy_boolean::chain Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/lazy-boolean.rs Number of expressions: 15 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -93,7 +93,7 @@ Highest counter ID seen: c6 Function name: lazy_boolean::nested_mixed Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/lazy-boolean.rs Number of expressions: 13 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add) diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map index 78507a326388..2af5e919f4c9 100644 --- a/tests/coverage/branch/let-else.cov-map +++ b/tests/coverage/branch/let-else.cov-map @@ -1,7 +1,7 @@ Function name: let_else::let_else Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0a, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/let-else.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 7 diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map index ef71d12c8af1..3f753f14eb5b 100644 --- a/tests/coverage/branch/match-arms.cov-map +++ b/tests/coverage/branch/match-arms.cov-map @@ -1,7 +1,7 @@ Function name: match_arms::guards Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 0e, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 28, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 28, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 28, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 28, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 15, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match-arms.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(5), rhs = Counter(1) - expression 1 operands: lhs = Counter(6), rhs = Counter(2) @@ -38,7 +38,7 @@ Highest counter ID seen: c8 Function name: match_arms::match_arms Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 20, 09, 01, 11, 00, 20, 0d, 01, 11, 00, 20, 02, 01, 11, 00, 20, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match-arms.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) @@ -57,7 +57,7 @@ Highest counter ID seen: c3 Function name: match_arms::or_patterns Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2d, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match-arms.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map index 1b0c6d12e3dc..dd05ae4e345f 100644 --- a/tests/coverage/branch/match-trivial.cov-map +++ b/tests/coverage/branch/match-trivial.cov-map @@ -1,7 +1,7 @@ Function name: match_trivial::_uninhabited (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match-trivial.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 22, 1) to (start + 1, 14) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: match_trivial::trivial Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 0e, 01, 03, 0b, 05, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match-trivial.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14) diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map index 8fb44ef30fdb..d28e6a580085 100644 --- a/tests/coverage/branch/no-mir-spans.cov-map +++ b/tests/coverage/branch/no-mir-spans.cov-map @@ -1,7 +1,7 @@ Function name: no_mir_spans::while_cond Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 11, 20, 02, 01, 04, 0b, 00, 10] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no-mir-spans.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 2 @@ -14,7 +14,7 @@ Highest counter ID seen: c0 Function name: no_mir_spans::while_cond_not Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 15, 20, 02, 01, 04, 0b, 00, 14] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no-mir-spans.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 2 @@ -27,7 +27,7 @@ Highest counter ID seen: c0 Function name: no_mir_spans::while_op_and Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 13, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no-mir-spans.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(2), rhs = Counter(1) - expression 1 operands: lhs = Counter(2), rhs = Counter(0) @@ -46,7 +46,7 @@ Highest counter ID seen: c1 Function name: no_mir_spans::while_op_or Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no-mir-spans.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(2), rhs = Counter(1) - expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add) diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map index 67746af051b6..e5fda26822e2 100644 --- a/tests/coverage/branch/while.cov-map +++ b/tests/coverage/branch/while.cov-map @@ -1,7 +1,7 @@ Function name: while::while_cond Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 6 @@ -19,7 +19,7 @@ Highest counter ID seen: c1 Function name: while::while_cond_not Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 6 @@ -37,7 +37,7 @@ Highest counter ID seen: c1 Function name: while::while_op_and Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(1), rhs = Counter(0) @@ -63,7 +63,7 @@ Highest counter ID seen: c2 Function name: while::while_op_or Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 2d784ba09b60..096be9ea78a0 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -1,7 +1,7 @@ Function name: closure::main Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0d, 1b, 01, 1a, 05, 02, 0a, 01, 0c, 05, 11, 1b, 01, 1e, 05, 02, 0a, 01, 0c, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 24 @@ -35,7 +35,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#0} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -49,7 +49,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#10} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 155, 7) to (start + 0, 33) @@ -58,7 +58,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#11} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 9f, 01, 07, 00, 21] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 159, 7) to (start + 0, 33) @@ -67,7 +67,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#12} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 01, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 167, 1) to (start + 0, 23) @@ -76,7 +76,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#13} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, ac, 01, 0d, 02, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 172, 13) to (start + 2, 14) @@ -85,7 +85,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#14} Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 @@ -98,7 +98,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#15} Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -114,7 +114,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#16} Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 @@ -127,7 +127,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#17} Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -143,7 +143,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#18} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -157,7 +157,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#19} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -171,7 +171,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#1} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 52, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -185,7 +185,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#2} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 68, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -199,7 +199,7 @@ Highest counter ID seen: c1 Function name: closure::main::{closure#3} (unused) Raw bytes (25): 0x[01, 01, 00, 04, 00, 81, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 129, 5) to (start + 1, 20) @@ -211,7 +211,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#4} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 89, 01, 35, 00, 43] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 137, 53) to (start + 0, 67) @@ -220,7 +220,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#5} Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 3d, 00, 4f] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 140, 61) to (start + 0, 79) @@ -229,7 +229,7 @@ Highest counter ID seen: c0 Function name: closure::main::{closure#6} Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 41, 00, 57] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 141, 65) to (start + 0, 87) @@ -238,7 +238,7 @@ Highest counter ID seen: c0 Function name: closure::main::{closure#7} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 3b, 00, 51] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 142, 59) to (start + 0, 81) @@ -247,7 +247,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#8} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 93, 01, 3b, 00, 55] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 147, 59) to (start + 0, 85) @@ -256,7 +256,7 @@ Highest counter ID seen: (none) Function name: closure::main::{closure#9} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 95, 01, 38, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 149, 56) to (start + 2, 6) diff --git a/tests/coverage/closure_bug.cov-map b/tests/coverage/closure_bug.cov-map index 40a8bdf9c1d6..8355cbf352b3 100644 --- a/tests/coverage/closure_bug.cov-map +++ b/tests/coverage/closure_bug.cov-map @@ -1,7 +1,7 @@ Function name: closure_bug::main Raw bytes (97): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 11, 01, 07, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_bug.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -34,7 +34,7 @@ Highest counter ID seen: c4 Function name: closure_bug::main::{closure#0} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -48,7 +48,7 @@ Highest counter ID seen: c1 Function name: closure_bug::main::{closure#1} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -62,7 +62,7 @@ Highest counter ID seen: c1 Function name: closure_bug::main::{closure#2} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -76,7 +76,7 @@ Highest counter ID seen: c1 Function name: closure_bug::main::{closure#3} Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map index 9dd99c8fab3f..c624896a720a 100644 --- a/tests/coverage/closure_macro.cov-map +++ b/tests/coverage/closure_macro.cov-map @@ -1,7 +1,7 @@ Function name: closure_macro::load_configuration_files Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: closure_macro::main Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -27,7 +27,7 @@ Highest counter ID seen: c1 Function name: closure_macro::main::{closure#0} Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 2548754d754c..77bf31de8bd8 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -1,7 +1,7 @@ Function name: closure_macro_async::load_configuration_files Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro_async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: closure_macro_async::test Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2b] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro_async.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 37, 1) to (start + 0, 43) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: closure_macro_async::test::{closure#0} Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro_async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 @@ -36,7 +36,7 @@ Highest counter ID seen: c1 Function name: closure_macro_async::test::{closure#0}::{closure#0} Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 14, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_macro_async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map index 9a66e0b0e772..c75119019fc8 100644 --- a/tests/coverage/closure_unit_return.cov-map +++ b/tests/coverage/closure_unit_return.cov-map @@ -1,7 +1,7 @@ Function name: closure_unit_return::explicit_unit Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16) @@ -11,7 +11,7 @@ Highest counter ID seen: c0 Function name: closure_unit_return::explicit_unit::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 8, 22) to (start + 2, 6) @@ -20,7 +20,7 @@ Highest counter ID seen: (none) Function name: closure_unit_return::implicit_unit Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16) @@ -30,7 +30,7 @@ Highest counter ID seen: c0 Function name: closure_unit_return::implicit_unit::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 17, 22) to (start + 2, 6) diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map index c34075a0bcfc..1bcf045b8942 100644 --- a/tests/coverage/condition/conditions.cov-map +++ b/tests/coverage/condition/conditions.cov-map @@ -1,7 +1,7 @@ Function name: conditions::assign_3_and_or Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1c, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -30,7 +30,7 @@ Highest counter ID seen: c3 Function name: conditions::assign_3_or_and Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 17, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) @@ -58,7 +58,7 @@ Highest counter ID seen: c3 Function name: conditions::assign_and Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0d, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -79,7 +79,7 @@ Highest counter ID seen: c2 Function name: conditions::assign_or Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 12, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) @@ -102,7 +102,7 @@ Highest counter ID seen: c2 Function name: conditions::foo Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) @@ -111,7 +111,7 @@ Highest counter ID seen: c0 Function name: conditions::func_call Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -132,7 +132,7 @@ Highest counter ID seen: c2 Function name: conditions::simple_assign Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2) diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map index 2d12f4bf7744..86a317948132 100644 --- a/tests/coverage/conditions.cov-map +++ b/tests/coverage/conditions.cov-map @@ -1,7 +1,7 @@ Function name: conditions::main Raw bytes (533): 0x[01, 01, 47, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 97, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 97, 01, 15, 0d, 11, 19, 45, 19, 8f, 01, 45, 49, 8f, 01, 4d, 45, 49, 19, 8b, 01, 8f, 01, 4d, 45, 49, 97, 01, db, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, db, 01, 1d, 15, 19, 21, 39, 21, d3, 01, 39, 3d, d3, 01, 41, 39, 3d, 21, cf, 01, d3, 01, 41, 39, 3d, db, 01, 97, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, 97, 02, 25, 1d, 21, 29, 2d, 29, 8f, 02, 2d, 31, 8f, 02, 35, 2d, 31, 29, 8b, 02, 8f, 02, 35, 2d, 31, 97, 02, 9b, 02, 1d, 21, 25, 29, 44, 01, 03, 01, 02, 0c, 01, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 01, 0a, 06, 02, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 01, 12, 2a, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 03, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 97, 01, 03, 08, 00, 0c, 97, 01, 01, 0d, 01, 10, 97, 01, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 97, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 6a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 72, 00, 21, 00, 2e, 76, 00, 32, 00, 40, 8b, 01, 00, 41, 02, 0e, 86, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 92, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, db, 01, 02, 09, 01, 0c, db, 01, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 97, 02, 02, 09, 00, 0a, db, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, ae, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, b6, 01, 00, 1d, 00, 2a, ba, 01, 00, 2e, 00, 3c, cf, 01, 00, 3d, 02, 0a, ca, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, d6, 01, 02, 0d, 02, 0f, 9b, 02, 05, 09, 00, 0a, 97, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, ea, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, f2, 01, 00, 1d, 00, 2a, f6, 01, 00, 2e, 00, 3c, 8b, 02, 00, 3d, 02, 0a, 86, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, 92, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/conditions.rs Number of expressions: 71 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map index d926741cbcb3..a8077a32df7d 100644 --- a/tests/coverage/continue.cov-map +++ b/tests/coverage/continue.cov-map @@ -1,7 +1,7 @@ Function name: continue::main Raw bytes (198): 0x[01, 01, 16, 05, 01, 05, 0b, 01, 09, 0d, 01, 0d, 1f, 01, 11, 0d, 1f, 01, 11, 15, 01, 15, 2b, 01, 19, 1d, 01, 1d, 37, 01, 21, 25, 01, 25, 43, 01, 29, 25, 01, 2d, 01, 53, 2d, 01, 31, 2d, 01, 1e, 01, 03, 01, 03, 12, 05, 04, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 06, 02, 12, 04, 0e, 0d, 06, 0e, 00, 13, 0e, 01, 0f, 00, 16, 1a, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 1a, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 22, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 26, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 2e, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 32, 01, 0a, 01, 0e, 25, 03, 0e, 00, 13, 46, 01, 0f, 00, 16, 3e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 46, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 56, 01, 16, 02, 0e, 4e, 04, 11, 00, 16, 56, 03, 09, 00, 0e, 01, 02, 0d, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/continue.rs Number of expressions: 22 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map index fee32376d831..0ce915538638 100644 --- a/tests/coverage/coroutine.cov-map +++ b/tests/coverage/coroutine.cov-map @@ -1,7 +1,7 @@ Function name: coroutine::get_u32 Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 01, 01, 0b, 05, 02, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coroutine.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -15,7 +15,7 @@ Highest counter ID seen: c1 Function name: coroutine::main Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coroutine.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -36,7 +36,7 @@ Highest counter ID seen: c3 Function name: coroutine::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 08, 01, 1f, 05, 02, 10, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coroutine.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 22, 8) to (start + 1, 31) diff --git a/tests/coverage/coverage_attr_closure.cov-map b/tests/coverage/coverage_attr_closure.cov-map index fb861996a0d2..e029a3b4643e 100644 --- a/tests/coverage/coverage_attr_closure.cov-map +++ b/tests/coverage/coverage_attr_closure.cov-map @@ -1,7 +1,7 @@ Function name: coverage_attr_closure::GLOBAL_CLOSURE_ON::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 0f, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 6, 15) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: coverage_attr_closure::contains_closures_off::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 13, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 29, 19) to (start + 2, 6) @@ -19,7 +19,7 @@ Highest counter ID seen: (none) Function name: coverage_attr_closure::contains_closures_on Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26) @@ -30,7 +30,7 @@ Highest counter ID seen: c0 Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 17, 19) to (start + 2, 6) diff --git a/tests/coverage/dead_code.cov-map b/tests/coverage/dead_code.cov-map index 897372fe0b5e..4cb311428a18 100644 --- a/tests/coverage/dead_code.cov-map +++ b/tests/coverage/dead_code.cov-map @@ -1,7 +1,7 @@ Function name: dead_code::main Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 1b, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/dead_code.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -15,7 +15,7 @@ Highest counter ID seen: c1 Function name: dead_code::unused_fn (unused) Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/dead_code.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 15, 1) to (start + 7, 15) @@ -27,7 +27,7 @@ Highest counter ID seen: (none) Function name: dead_code::unused_pub_fn_not_in_library (unused) Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/dead_code.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 3, 1) to (start + 7, 15) diff --git a/tests/coverage/drop_trait.cov-map b/tests/coverage/drop_trait.cov-map index 16facf2eddf2..a52ebd87aa82 100644 --- a/tests/coverage/drop_trait.cov-map +++ b/tests/coverage/drop_trait.cov-map @@ -1,7 +1,7 @@ Function name: ::drop Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/drop_trait.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 9, 5) to (start + 2, 6) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: drop_trait::main Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 01, 05, 0c, 01, 06, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/drop_trait.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 14, 1) to (start + 5, 12) diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map index 6d6034928c9a..465baa7f7f9b 100644 --- a/tests/coverage/fn_sig_into_try.cov-map +++ b/tests/coverage/fn_sig_into_try.cov-map @@ -1,7 +1,7 @@ Function name: fn_sig_into_try::a Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 05, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 1) to (start + 5, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: fn_sig_into_try::b Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15) @@ -22,7 +22,7 @@ Highest counter ID seen: c0 Function name: fn_sig_into_try::c Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23) @@ -34,7 +34,7 @@ Highest counter ID seen: c0 Function name: fn_sig_into_try::d Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15) diff --git a/tests/coverage/generic-unused-impl.cov-map b/tests/coverage/generic-unused-impl.cov-map index 5878de231bad..119c426965d1 100644 --- a/tests/coverage/generic-unused-impl.cov-map +++ b/tests/coverage/generic-unused-impl.cov-map @@ -1,7 +1,7 @@ Function name: as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 03, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generic-unused-impl.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 11, 5) to (start + 3, 6) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: generic_unused_impl::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 0d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generic-unused-impl.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 1) to (start + 0, 13) diff --git a/tests/coverage/generics.cov-map b/tests/coverage/generics.cov-map index bc5661afdc19..92c6ad01e300 100644 --- a/tests/coverage/generics.cov-map +++ b/tests/coverage/generics.cov-map @@ -1,7 +1,7 @@ Function name: as core::ops::drop::Drop>::drop Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: >::set_strength Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: as core::ops::drop::Drop>::drop Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) @@ -28,7 +28,7 @@ Highest counter ID seen: c0 Function name: >::set_strength Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6) @@ -37,7 +37,7 @@ Highest counter ID seen: c0 Function name: generics::main Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 08, 0c, 01, 09, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 22, 1) to (start + 8, 12) diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map index 6e2d243e8dd2..5298c2d92d5d 100644 --- a/tests/coverage/holes.cov-map +++ b/tests/coverage/holes.cov-map @@ -1,7 +1,7 @@ Function name: ::_method (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/holes.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 43, 9) to (start + 0, 29) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: holes::main Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 11, 01, 05, 05, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 11, 01, 04, 05, 00, 11, 01, 07, 05, 00, 11, 01, 06, 05, 00, 11, 01, 04, 05, 00, 11, 01, 04, 05, 00, 11, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 06, 27, 01, 13, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/holes.rs Number of expressions: 0 Number of file 0 mappings: 13 - Code(Counter(0)) at (prev + 8, 1) to (start + 1, 17) @@ -31,7 +31,7 @@ Highest counter ID seen: c0 Function name: holes::main::_unused_fn (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/holes.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 31, 5) to (start + 0, 23) @@ -40,7 +40,7 @@ Highest counter ID seen: (none) Function name: holes::main::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/holes.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 24, 9) to (start + 2, 10) @@ -49,7 +49,7 @@ Highest counter ID seen: (none) Function name: holes::main::{closure#1} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/holes.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 75, 9) to (start + 2, 10) diff --git a/tests/coverage/if.cov-map b/tests/coverage/if.cov-map index a77ba8194a44..611dd2ef08d5 100644 --- a/tests/coverage/if.cov-map +++ b/tests/coverage/if.cov-map @@ -1,7 +1,7 @@ Function name: if::main Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 04, 01, 12, 10, 05, 13, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 diff --git a/tests/coverage/if_else.cov-map b/tests/coverage/if_else.cov-map index 194ad6ca71f8..35096d859502 100644 --- a/tests/coverage/if_else.cov-map +++ b/tests/coverage/if_else.cov-map @@ -1,7 +1,7 @@ Function name: if_else::main Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 08, 10, 05, 09, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if_else.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map index f47139ce5a48..0fd35c55e3e5 100644 --- a/tests/coverage/if_not.cov-map +++ b/tests/coverage/if_not.cov-map @@ -1,7 +1,7 @@ Function name: if_not::if_not Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if_not.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) diff --git a/tests/coverage/ignore_run.cov-map b/tests/coverage/ignore_run.cov-map index c8ad3821e16f..a93fff71530b 100644 --- a/tests/coverage/ignore_run.cov-map +++ b/tests/coverage/ignore_run.cov-map @@ -1,7 +1,7 @@ Function name: ignore_run::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/ignore_run.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13) diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map index 65cefe76c29a..450fb75b7c8e 100644 --- a/tests/coverage/inline-dead.cov-map +++ b/tests/coverage/inline-dead.cov-map @@ -1,7 +1,7 @@ Function name: inline_dead::dead (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline-dead.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 23, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: inline_dead::live:: Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline-dead.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -24,7 +24,7 @@ Highest counter ID seen: c1 Function name: inline_dead::main Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline-dead.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10) @@ -34,7 +34,7 @@ Highest counter ID seen: c0 Function name: inline_dead::main::{closure#0} Raw bytes (19): 0x[01, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 01, 01, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline-dead.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22) diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map index 7264391baaf7..5aa57e15bd5c 100644 --- a/tests/coverage/inline.cov-map +++ b/tests/coverage/inline.cov-map @@ -1,7 +1,7 @@ Function name: inline::display:: Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 29, 01, 00, 22, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 5 @@ -17,7 +17,7 @@ Highest counter ID seen: c1 Function name: inline::error Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 0b] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 49, 1) to (start + 1, 11) @@ -26,7 +26,7 @@ Highest counter ID seen: c0 Function name: inline::length:: Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2) @@ -35,7 +35,7 @@ Highest counter ID seen: c0 Function name: inline::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2) @@ -44,7 +44,7 @@ Highest counter ID seen: c0 Function name: inline::permutate:: Raw bytes (54): 0x[01, 01, 05, 01, 05, 0d, 09, 0d, 09, 01, 13, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 0a, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 0a, 00, 17, 04, 0a, 0e, 05, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(3), rhs = Counter(2) @@ -69,7 +69,7 @@ Highest counter ID seen: c2 Function name: inline::permutations:: Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 1) to (start + 3, 2) @@ -78,7 +78,7 @@ Highest counter ID seen: c0 Function name: inline::swap:: Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 04, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inline.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 35, 1) to (start + 4, 2) diff --git a/tests/coverage/inner_items.cov-map b/tests/coverage/inner_items.cov-map index a12cce25b643..a9e19fe53a53 100644 --- a/tests/coverage/inner_items.cov-map +++ b/tests/coverage/inner_items.cov-map @@ -1,7 +1,7 @@ Function name: ::default_trait_func Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 09, 03, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inner_items.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 9) to (start + 3, 10) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: ::trait_func Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 09, 03, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inner_items.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 40, 9) to (start + 3, 10) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: inner_items::main Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 05, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inner_items.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -38,7 +38,7 @@ Highest counter ID seen: c2 Function name: inner_items::main::in_func Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 05, 04, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inner_items.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 18, 5) to (start + 4, 6) diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index f10231090089..4e45db836d67 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,7 +1,7 @@ Function name: issue_83601::main Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-83601.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 3 diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 47e2922a805a..1ed5edbb8191 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -1,7 +1,7 @@ Function name: ::fmt Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 24, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -15,7 +15,7 @@ Highest counter ID seen: c1 Function name: issue_84561::main Raw bytes (10): 0x[01, 01, 00, 01, 01, b4, 01, 01, 04, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 180, 1) to (start + 4, 2) @@ -24,7 +24,7 @@ Highest counter ID seen: c0 Function name: issue_84561::test1 Raw bytes (50): 0x[01, 01, 00, 09, 01, 9a, 01, 01, 01, 0b, 05, 01, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 01, 0b, 0d, 01, 0c, 00, 1e, 01, 01, 05, 03, 0b, 11, 03, 0c, 00, 1e, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 0 Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 154, 1) to (start + 1, 11) @@ -41,7 +41,7 @@ Highest counter ID seen: c4 Function name: issue_84561::test2 Raw bytes (20): 0x[01, 01, 00, 03, 01, b0, 01, 01, 01, 10, 05, 01, 11, 00, 23, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 176, 1) to (start + 1, 16) @@ -52,7 +52,7 @@ Highest counter ID seen: c1 Function name: issue_84561::test2::call_print Raw bytes (10): 0x[01, 01, 00, 01, 01, a7, 01, 09, 02, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10) @@ -61,7 +61,7 @@ Highest counter ID seen: c0 Function name: issue_84561::test3 Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-84561.rs Number of expressions: 10 - expression 0 operands: lhs = Counter(3), rhs = Counter(4) - expression 1 operands: lhs = Counter(3), rhs = Counter(5) diff --git a/tests/coverage/issue-85461.cov-map b/tests/coverage/issue-85461.cov-map index 349bc2cab803..566206a7539d 100644 --- a/tests/coverage/issue-85461.cov-map +++ b/tests/coverage/issue-85461.cov-map @@ -1,7 +1,7 @@ Function name: issue_85461::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-85461.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2) diff --git a/tests/coverage/issue-93054.cov-map b/tests/coverage/issue-93054.cov-map index 38cb70a3f97a..3cb54d80e7f0 100644 --- a/tests/coverage/issue-93054.cov-map +++ b/tests/coverage/issue-93054.cov-map @@ -1,7 +1,7 @@ Function name: issue_93054::foo2 (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-93054.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 21, 1) to (start + 0, 29) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: issue_93054::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 0d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-93054.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 29, 1) to (start + 0, 13) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: issue_93054::make (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/issue-93054.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 25, 1) to (start + 2, 2) diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map index 3f7788da1ebc..9722b4c2a325 100644 --- a/tests/coverage/lazy_boolean.cov-map +++ b/tests/coverage/lazy_boolean.cov-map @@ -1,7 +1,7 @@ Function name: lazy_boolean::main Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/lazy_boolean.rs Number of expressions: 7 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(9) diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map index 7789114c2395..f55e5a930b47 100644 --- a/tests/coverage/let_else_loop.cov-map +++ b/tests/coverage/let_else_loop.cov-map @@ -1,7 +1,7 @@ Function name: let_else_loop::_if (unused) Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/let_else_loop.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Zero) at (prev + 22, 1) to (start + 1, 12) @@ -12,7 +12,7 @@ Highest counter ID seen: (none) Function name: let_else_loop::_loop_either_way (unused) Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/let_else_loop.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Zero) at (prev + 15, 1) to (start + 1, 20) @@ -23,7 +23,7 @@ Highest counter ID seen: (none) Function name: let_else_loop::loopy Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/let_else_loop.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20) diff --git a/tests/coverage/long_and_wide.cov-map b/tests/coverage/long_and_wide.cov-map index 032b7fe102e8..c8194ccc79b3 100644 --- a/tests/coverage/long_and_wide.cov-map +++ b/tests/coverage/long_and_wide.cov-map @@ -1,7 +1,7 @@ Function name: long_and_wide::far_function Raw bytes (10): 0x[01, 01, 00, 01, 01, 96, 01, 01, 00, 15] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/long_and_wide.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 150, 1) to (start + 0, 21) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: long_and_wide::long_function Raw bytes (10): 0x[01, 01, 00, 01, 01, 10, 01, 84, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/long_and_wide.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 16, 1) to (start + 132, 2) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: long_and_wide::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 04, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/long_and_wide.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 7, 1) to (start + 4, 2) @@ -28,7 +28,7 @@ Highest counter ID seen: c0 Function name: long_and_wide::wide_function Raw bytes (10): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 8b, 01] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/long_and_wide.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 139) diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map index fccc4d64395b..8edb6d06dd6d 100644 --- a/tests/coverage/loop-break.cov-map +++ b/tests/coverage/loop-break.cov-map @@ -1,7 +1,7 @@ Function name: loop_break::main Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/loop-break.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 5 diff --git a/tests/coverage/loop_break_value.cov-map b/tests/coverage/loop_break_value.cov-map index e48d078f6722..d16335a0a291 100644 --- a/tests/coverage/loop_break_value.cov-map +++ b/tests/coverage/loop_break_value.cov-map @@ -1,7 +1,7 @@ Function name: loop_break_value::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 0a, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/loop_break_value.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 4, 1) to (start + 10, 2) diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index 2157cd6ee3f8..d414710ee9d6 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,7 +1,7 @@ Function name: ::fmt Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/loops_branches.rs Number of expressions: 4 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) - expression 1 operands: lhs = Counter(0), rhs = Counter(3) @@ -35,7 +35,7 @@ Highest counter ID seen: c3 Function name: ::fmt Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/loops_branches.rs Number of expressions: 4 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -69,7 +69,7 @@ Highest counter ID seen: c3 Function name: loops_branches::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/loops_branches.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 55, 1) to (start + 5, 2) diff --git a/tests/coverage/macro_in_closure.cov-map b/tests/coverage/macro_in_closure.cov-map index 9614154a3668..3e71ed877bf9 100644 --- a/tests/coverage/macro_in_closure.cov-map +++ b/tests/coverage/macro_in_closure.cov-map @@ -1,7 +1,7 @@ Function name: macro_in_closure::NO_BLOCK::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 1c, 00, 2d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/macro_in_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 7, 28) to (start + 0, 45) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: macro_in_closure::WITH_BLOCK::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 1e, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/macro_in_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 9, 30) to (start + 2, 2) diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map index bd033faa5510..18b4e28b7b43 100644 --- a/tests/coverage/macro_name_span.cov-map +++ b/tests/coverage/macro_name_span.cov-map @@ -1,7 +1,7 @@ Function name: macro_name_span::affected_function Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 3e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/macro_name_span.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 22, 28) to (start + 1, 62) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: macro_name_span::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/macro_name_span.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map index ae77eedfe72e..a29c712998f7 100644 --- a/tests/coverage/match_or_pattern.cov-map +++ b/tests/coverage/match_or_pattern.cov-map @@ -1,7 +1,7 @@ Function name: match_or_pattern::main Raw bytes (145): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/match_or_pattern.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map index befe8866a592..f966d754f540 100644 --- a/tests/coverage/mcdc/condition-limit.cov-map +++ b/tests/coverage/mcdc/condition-limit.cov-map @@ -1,7 +1,7 @@ Function name: condition_limit::accept_7_conditions Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/condition-limit.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map index 1b038f48429e..de4ea7790f75 100644 --- a/tests/coverage/mcdc/if.cov-map +++ b/tests/coverage/mcdc/if.cov-map @@ -1,7 +1,7 @@ Function name: if::mcdc_check_a Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -25,7 +25,7 @@ Highest counter ID seen: c2 Function name: if::mcdc_check_b Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -49,7 +49,7 @@ Highest counter ID seen: c2 Function name: if::mcdc_check_both Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -73,7 +73,7 @@ Highest counter ID seen: c2 Function name: if::mcdc_check_neither Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -97,7 +97,7 @@ Highest counter ID seen: c2 Function name: if::mcdc_check_not_tree_decision Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 7 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add) @@ -131,7 +131,7 @@ Highest counter ID seen: c3 Function name: if::mcdc_check_tree_decision Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 8 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -166,7 +166,7 @@ Highest counter ID seen: c3 Function name: if::mcdc_nested_if Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/if.rs Number of expressions: 11 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(10, Add) diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map index 7d78e572a3b0..714d168cf498 100644 --- a/tests/coverage/mcdc/inlined_expressions.cov-map +++ b/tests/coverage/mcdc/inlined_expressions.cov-map @@ -1,7 +1,7 @@ Function name: inlined_expressions::inlined_instance Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/inlined_expressions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map index 83d0739aaf59..7232e4f89cdd 100644 --- a/tests/coverage/mcdc/nested_if.cov-map +++ b/tests/coverage/mcdc/nested_if.cov-map @@ -1,7 +1,7 @@ Function name: nested_if::doubly_nested_if_in_condition Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested_if.rs Number of expressions: 15 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(4) @@ -61,7 +61,7 @@ Highest counter ID seen: c6 Function name: nested_if::nested_if_in_condition Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested_if.rs Number of expressions: 10 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(4) @@ -105,7 +105,7 @@ Highest counter ID seen: c4 Function name: nested_if::nested_in_then_block_in_condition Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested_if.rs Number of expressions: 15 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(6) @@ -165,7 +165,7 @@ Highest counter ID seen: c6 Function name: nested_if::nested_single_condition_decision Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested_if.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(3) diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map index 48a103b2c7d7..02251e691522 100644 --- a/tests/coverage/mcdc/non_control_flow.cov-map +++ b/tests/coverage/mcdc/non_control_flow.cov-map @@ -1,7 +1,7 @@ Function name: non_control_flow::assign_3 Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) @@ -30,7 +30,7 @@ Highest counter ID seen: c3 Function name: non_control_flow::assign_3_bis Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -60,7 +60,7 @@ Highest counter ID seen: c3 Function name: non_control_flow::assign_and Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -82,7 +82,7 @@ Highest counter ID seen: c2 Function name: non_control_flow::assign_or Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) @@ -106,7 +106,7 @@ Highest counter ID seen: c2 Function name: non_control_flow::foo Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2) @@ -115,7 +115,7 @@ Highest counter ID seen: c0 Function name: non_control_flow::func_call Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -137,7 +137,7 @@ Highest counter ID seen: c2 Function name: non_control_flow::right_comb_tree Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/non_control_flow.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map index e9e41bd53e78..4a35da13a847 100644 --- a/tests/coverage/nested_loops.cov-map +++ b/tests/coverage/nested_loops.cov-map @@ -1,7 +1,7 @@ Function name: nested_loops::main Raw bytes (97): 0x[01, 01, 0e, 07, 2f, 05, 11, 01, 0d, 2f, 05, 01, 0d, 27, 05, 01, 09, 33, 27, 05, 15, 01, 09, 2f, 33, 01, 0d, 05, 15, 05, 01, 0d, 01, 01, 01, 02, 1b, 05, 04, 13, 00, 20, 09, 01, 0d, 01, 18, 0d, 02, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 0e, 01, 0e, 03, 16, 15, 04, 11, 01, 1b, 16, 02, 15, 00, 21, 1e, 01, 18, 02, 12, 2a, 03, 0d, 00, 0e, 36, 02, 09, 00, 17, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/nested_loops.rs Number of expressions: 14 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(11, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(4) diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map index 3a1ca4745c73..89012b0ab917 100644 --- a/tests/coverage/no-core.cov-map +++ b/tests/coverage/no-core.cov-map @@ -1,7 +1,7 @@ Function name: no_core::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no-core.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13) diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map index 244b0099544b..caef09355d22 100644 --- a/tests/coverage/no_cov_crate.cov-map +++ b/tests/coverage/no_cov_crate.cov-map @@ -1,7 +1,7 @@ Function name: no_cov_crate::add_coverage_1 Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 22, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_2 Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_not_called (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 31, 1) to (start + 2, 2) @@ -28,7 +28,7 @@ Highest counter ID seen: (none) Function name: no_cov_crate::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 4f, 01, 0b, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 79, 1) to (start + 11, 2) @@ -37,7 +37,7 @@ Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 22, 01, 0c, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 51, 5) to (start + 2, 34) @@ -47,7 +47,7 @@ Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 16, 01, 0b, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 65, 5) to (start + 2, 22) @@ -57,7 +57,7 @@ Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered::inner Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 45, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_cov_crate.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 diff --git a/tests/coverage/no_spans.cov-map b/tests/coverage/no_spans.cov-map index 7f43b68fa904..992247fd520b 100644 --- a/tests/coverage/no_spans.cov-map +++ b/tests/coverage/no_spans.cov-map @@ -1,7 +1,7 @@ Function name: no_spans::affected_function Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_spans.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: no_spans::affected_function::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_spans.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14) diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map index 6c389a243172..9d4fc074111f 100644 --- a/tests/coverage/no_spans_if_not.cov-map +++ b/tests/coverage/no_spans_if_not.cov-map @@ -1,7 +1,7 @@ Function name: no_spans_if_not::affected_function Raw bytes (19): 0x[01, 01, 00, 03, 01, 16, 1c, 01, 12, 01, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_spans_if_not.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18) @@ -12,7 +12,7 @@ Highest counter ID seen: c0 Function name: no_spans_if_not::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/no_spans_if_not.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map index 1178d65de102..9bb68ee107dd 100644 --- a/tests/coverage/overflow.cov-map +++ b/tests/coverage/overflow.cov-map @@ -1,7 +1,7 @@ Function name: overflow::main Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 10, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 06, 03, 13, 00, 20, 0d, 00, 21, 03, 0a, 0e, 03, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/overflow.rs Number of expressions: 6 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add) @@ -28,7 +28,7 @@ Highest counter ID seen: c3 Function name: overflow::might_overflow Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 05, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/overflow.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map index 18b13919fe5e..f6d1fe5b9b48 100644 --- a/tests/coverage/panic_unwind.cov-map +++ b/tests/coverage/panic_unwind.cov-map @@ -1,7 +1,7 @@ Function name: panic_unwind::main Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/panic_unwind.rs Number of expressions: 6 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add) @@ -28,7 +28,7 @@ Highest counter ID seen: c3 Function name: panic_unwind::might_panic Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/panic_unwind.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 diff --git a/tests/coverage/partial_eq.cov-map b/tests/coverage/partial_eq.cov-map index 21c8714ac99b..02054aa444a5 100644 --- a/tests/coverage/partial_eq.cov-map +++ b/tests/coverage/partial_eq.cov-map @@ -1,7 +1,7 @@ Function name: ::new Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 05, 02, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/partial_eq.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 12, 5) to (start + 2, 6) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: partial_eq::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 0a, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/partial_eq.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 1) to (start + 10, 2) diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map index 8e428b267d56..542c93cbfa05 100644 --- a/tests/coverage/simple_loop.cov-map +++ b/tests/coverage/simple_loop.cov-map @@ -1,7 +1,7 @@ Function name: simple_loop::main Raw bytes (43): 0x[01, 01, 02, 01, 05, 09, 01, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 06, 02, 0a, 03, 0a, 01, 06, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/simple_loop.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(2), rhs = Counter(0) diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map index 15f114daa7fb..a96ddc2bb9ae 100644 --- a/tests/coverage/simple_match.cov-map +++ b/tests/coverage/simple_match.cov-map @@ -1,7 +1,7 @@ Function name: simple_match::main Raw bytes (64): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0e, 0a, 0d, 00, 0f, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/simple_match.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(2), rhs = Counter(0) diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map index 898d68171c50..b0d260efeb9a 100644 --- a/tests/coverage/sort_groups.cov-map +++ b/tests/coverage/sort_groups.cov-map @@ -1,7 +1,7 @@ Function name: sort_groups::generic_fn::<&str> Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -15,7 +15,7 @@ Highest counter ID seen: c1 Function name: sort_groups::generic_fn::<()> Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -29,7 +29,7 @@ Highest counter ID seen: c1 Function name: sort_groups::generic_fn:: Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -43,7 +43,7 @@ Highest counter ID seen: c1 Function name: sort_groups::generic_fn:: Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -57,7 +57,7 @@ Highest counter ID seen: c1 Function name: sort_groups::main Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 1c, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -71,7 +71,7 @@ Highest counter ID seen: c1 Function name: sort_groups::other_fn Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 11] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/sort_groups.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 23, 1) to (start + 0, 17) diff --git a/tests/coverage/test_harness.cov-map b/tests/coverage/test_harness.cov-map index b513b3d05494..50654fb22137 100644 --- a/tests/coverage/test_harness.cov-map +++ b/tests/coverage/test_harness.cov-map @@ -1,7 +1,7 @@ Function name: test_harness::my_test Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 10] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/test_harness.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 1) to (start + 0, 16) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: test_harness::unused (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/test_harness.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 7, 1) to (start + 0, 15) diff --git a/tests/coverage/tight_inf_loop.cov-map b/tests/coverage/tight_inf_loop.cov-map index 77a8ffb83581..31581f0872f9 100644 --- a/tests/coverage/tight_inf_loop.cov-map +++ b/tests/coverage/tight_inf_loop.cov-map @@ -1,7 +1,7 @@ Function name: tight_inf_loop::main Raw bytes (19): 0x[01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 01, 01, 06, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/tight_inf_loop.rs Number of expressions: 0 Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 1, 1) to (start + 1, 13) diff --git a/tests/coverage/trivial.cov-map b/tests/coverage/trivial.cov-map index 05f64896d9ec..0064b20480f3 100644 --- a/tests/coverage/trivial.cov-map +++ b/tests/coverage/trivial.cov-map @@ -1,7 +1,7 @@ Function name: trivial::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/trivial.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13) diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index e45f3de10815..a6ecc68ab0e8 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -1,7 +1,7 @@ Function name: ::get_thing_2 Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -15,7 +15,7 @@ Highest counter ID seen: c1 Function name: ::call Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 34, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -29,7 +29,7 @@ Highest counter ID seen: c1 Function name: try_error_result::call Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 14, 05, 02, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -43,7 +43,7 @@ Highest counter ID seen: c1 Function name: try_error_result::main Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0a, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -57,7 +57,7 @@ Highest counter ID seen: c1 Function name: try_error_result::test1 Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 4 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) @@ -84,7 +84,7 @@ Highest counter ID seen: c2 Function name: try_error_result::test2 Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 1c, 15, 04, 11, 00, 12, 1e, 02, 11, 03, 27, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 29, 19, 00, 41, 00, 42, 26, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 17, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 29, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 47, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 17, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 29, 29, 00, 42, 00, 43, 66, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 17, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 1d, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 17, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 1d, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 17, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/try_error_result.rs Number of expressions: 54 - expression 0 operands: lhs = Counter(3), rhs = Counter(4) - expression 1 operands: lhs = Counter(3), rhs = Expression(15, Add) diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map index 29d40a055130..7ad4395491f0 100644 --- a/tests/coverage/unicode.cov-map +++ b/tests/coverage/unicode.cov-map @@ -1,7 +1,7 @@ Function name: unicode::main Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unicode.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(0), rhs = Counter(3) @@ -23,7 +23,7 @@ Highest counter ID seen: c3 Function name: unicode::他 (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unicode.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 30, 25) to (start + 0, 37) @@ -32,7 +32,7 @@ Highest counter ID seen: (none) Function name: unicode::申し訳ございません Raw bytes (9): 0x[01, 01, 00, 01, 01, 18, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unicode.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2) diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map index 0bc18bfcbd31..fd9a1abc8cb0 100644 --- a/tests/coverage/unreachable.cov-map +++ b/tests/coverage/unreachable.cov-map @@ -1,7 +1,7 @@ Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 45] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unreachable.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 14, 39) to (start + 0, 69) @@ -10,7 +10,7 @@ Highest counter ID seen: (none) Function name: unreachable::unreachable_function (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 23] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unreachable.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 16, 1) to (start + 1, 35) @@ -19,7 +19,7 @@ Highest counter ID seen: (none) Function name: unreachable::unreachable_intrinsic (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2a] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unreachable.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 21, 1) to (start + 1, 42) diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map index c18d331ec2e0..8946b43a8bbc 100644 --- a/tests/coverage/unused.cov-map +++ b/tests/coverage/unused.cov-map @@ -1,7 +1,7 @@ Function name: unused::foo:: Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) @@ -21,7 +21,7 @@ Highest counter ID seen: c1 Function name: unused::foo:: Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) @@ -41,7 +41,7 @@ Highest counter ID seen: c1 Function name: unused::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 04, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2) @@ -50,7 +50,7 @@ Highest counter ID seen: c0 Function name: unused::unused_func (unused) Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 19, 1) to (start + 1, 14) @@ -62,7 +62,7 @@ Highest counter ID seen: (none) Function name: unused::unused_func2 (unused) Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 25, 1) to (start + 1, 14) @@ -74,7 +74,7 @@ Highest counter ID seen: (none) Function name: unused::unused_func3 (unused) Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Zero) at (prev + 31, 1) to (start + 1, 14) @@ -86,7 +86,7 @@ Highest counter ID seen: (none) Function name: unused::unused_template_func::<_> (unused) Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused.rs Number of expressions: 0 Number of file 0 mappings: 6 - Code(Zero) at (prev + 11, 1) to (start + 1, 18) diff --git a/tests/coverage/unused_mod.cov-map b/tests/coverage/unused_mod.cov-map index 5e8b69fcdba9..790cd701dc3a 100644 --- a/tests/coverage/unused_mod.cov-map +++ b/tests/coverage/unused_mod.cov-map @@ -1,7 +1,7 @@ Function name: unused_mod::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/unused_mod.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: unused_mod::unused_module::never_called_function (unused) Raw bytes (9): 0x[01, 02, 00, 01, 00, 02, 01, 02, 02] Number of files: 1 -- file 0 => global file 2 +- file 0 => $DIR/auxiliary/unused_mod_helper.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Zero) at (prev + 2, 1) to (start + 2, 2) diff --git a/tests/coverage/uses_crate.cov-map b/tests/coverage/uses_crate.cov-map index 5c23f8826971..238226f3d683 100644 --- a/tests/coverage/uses_crate.cov-map +++ b/tests/coverage/uses_crate.cov-map @@ -1,7 +1,7 @@ Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::> Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec> Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2) @@ -19,7 +19,7 @@ Highest counter ID seen: c0 Function name: used_crate::used_only_from_bin_crate_generic_function::<&str> Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2) @@ -28,7 +28,7 @@ Highest counter ID seen: c0 Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str> Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2) @@ -37,7 +37,7 @@ Highest counter ID seen: c0 Function name: uses_crate::main Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02] Number of files: 1 -- file 0 => global file 2 +- file 0 => $DIR/uses_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2) diff --git a/tests/coverage/uses_inline_crate.cov-map b/tests/coverage/uses_inline_crate.cov-map index a482d20e3b4b..fd14ea341202 100644 --- a/tests/coverage/uses_inline_crate.cov-map +++ b/tests/coverage/uses_inline_crate.cov-map @@ -1,7 +1,7 @@ Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::> Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2) @@ -10,7 +10,7 @@ Highest counter ID seen: c0 Function name: used_inline_crate::used_inline_function Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 01, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 @@ -24,7 +24,7 @@ Highest counter ID seen: c1 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec> Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) @@ -33,7 +33,7 @@ Highest counter ID seen: c0 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str> Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) @@ -42,7 +42,7 @@ Highest counter ID seen: c0 Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str> Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2) @@ -51,7 +51,7 @@ Highest counter ID seen: c0 Function name: uses_inline_crate::main Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02] Number of files: 1 -- file 0 => global file 2 +- file 0 => $DIR/uses_inline_crate.rs Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2) diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map index 5a6698128cbd..8ad739206297 100644 --- a/tests/coverage/while.cov-map +++ b/tests/coverage/while.cov-map @@ -1,7 +1,7 @@ Function name: while::main Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 01, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16) diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map index 69b51bf9ca34..6e3db66f97c7 100644 --- a/tests/coverage/while_early_ret.cov-map +++ b/tests/coverage/while_early_ret.cov-map @@ -1,7 +1,7 @@ Function name: while_early_ret::main Raw bytes (63): 0x[01, 01, 07, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 09, 09, 01, 05, 01, 01, 1b, 05, 03, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 16, 03, 0a, 03, 0a, 1a, 06, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/while_early_ret.rs Number of expressions: 7 - expression 0 operands: lhs = Expression(3, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map index bf0916e5503a..db82c9d673d1 100644 --- a/tests/coverage/yield.cov-map +++ b/tests/coverage/yield.cov-map @@ -1,7 +1,7 @@ Function name: yield::main Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/yield.rs Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) @@ -35,7 +35,7 @@ Highest counter ID seen: c5 Function name: yield::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 09, 08, 01, 10, 05, 02, 10, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/yield.rs Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 9, 8) to (start + 1, 16) @@ -45,7 +45,7 @@ Highest counter ID seen: c1 Function name: yield::main::{closure#1} Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 08, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06] Number of files: 1 -- file 0 => global file 1 +- file 0 => $DIR/yield.rs Number of expressions: 0 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 24, 8) to (start + 1, 16) From c35914383a92d7504f3a71c390dc2ebd14bce695 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 15 Mar 2025 11:19:56 -0700 Subject: [PATCH 186/262] Consistent trait bounds for ExtractIf Debug impls --- library/alloc/src/collections/btree/map.rs | 11 +++++------ library/alloc/src/collections/btree/set.rs | 13 ++++++------- library/alloc/src/collections/linked_list.rs | 9 +++++++-- library/alloc/src/vec/extract_if.rs | 15 +++++++++++++-- library/std/src/collections/hash/map.rs | 20 +++++++++----------- library/std/src/collections/hash/set.rs | 19 ++++++++----------- tests/rustdoc-js-std/path-maxeditdistance.js | 2 +- 7 files changed, 49 insertions(+), 40 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 78b7da9d6b3e..5ca32ed741af 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1917,14 +1917,13 @@ pub struct ExtractIf< V, F, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, -> where - F: 'a + FnMut(&K, &mut V) -> bool, -{ +> { pred: F, inner: ExtractIfInner<'a, K, V>, /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`. alloc: A, } + /// Most of the implementation of ExtractIf are generic over the type /// of the predicate, thus also serving for BTreeSet::ExtractIf. pub(super) struct ExtractIfInner<'a, K, V> { @@ -1940,14 +1939,14 @@ pub(super) struct ExtractIfInner<'a, K, V> { } #[unstable(feature = "btree_extract_if", issue = "70530")] -impl fmt::Debug for ExtractIf<'_, K, V, F> +impl fmt::Debug for ExtractIf<'_, K, V, F, A> where K: fmt::Debug, V: fmt::Debug, - F: FnMut(&K, &mut V) -> bool, + A: Allocator + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("ExtractIf").field(&self.inner.peek()).finish() + f.debug_struct("ExtractIf").field("peek", &self.inner.peek()).finish_non_exhaustive() } } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 7ad9e59dfede..343934680b87 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1556,10 +1556,7 @@ pub struct ExtractIf< T, F, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, -> where - T: 'a, - F: 'a + FnMut(&T) -> bool, -{ +> { pred: F, inner: super::map::ExtractIfInner<'a, T, SetValZST>, /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`. @@ -1567,13 +1564,15 @@ pub struct ExtractIf< } #[unstable(feature = "btree_extract_if", issue = "70530")] -impl fmt::Debug for ExtractIf<'_, T, F, A> +impl fmt::Debug for ExtractIf<'_, T, F, A> where T: fmt::Debug, - F: FnMut(&T) -> bool, + A: Allocator + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("ExtractIf").field(&self.inner.peek().map(|(k, _)| k)).finish() + f.debug_struct("ExtractIf") + .field("peek", &self.inner.peek().map(|(k, _)| k)) + .finish_non_exhaustive() } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index cc42a120e4fa..00e2805d11f6 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1976,9 +1976,14 @@ where } #[stable(feature = "extract_if", since = "1.87.0")] -impl fmt::Debug for ExtractIf<'_, T, F> { +impl fmt::Debug for ExtractIf<'_, T, F, A> +where + T: fmt::Debug, + A: Allocator, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("ExtractIf").field(&self.list).finish() + let peek = self.it.map(|node| unsafe { &node.as_ref().element }); + f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive() } } diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs index 8a591a877964..a456d3d9e602 100644 --- a/library/alloc/src/vec/extract_if.rs +++ b/library/alloc/src/vec/extract_if.rs @@ -1,5 +1,5 @@ use core::ops::{Range, RangeBounds}; -use core::{ptr, slice}; +use core::{fmt, ptr, slice}; use super::Vec; use crate::alloc::{Allocator, Global}; @@ -16,7 +16,6 @@ use crate::alloc::{Allocator, Global}; /// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0); /// ``` #[stable(feature = "extract_if", since = "1.87.0")] -#[derive(Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ExtractIf< 'a, @@ -108,3 +107,15 @@ impl Drop for ExtractIf<'_, T, F, A> { } } } + +#[stable(feature = "extract_if", since = "1.87.0")] +impl fmt::Debug for ExtractIf<'_, T, F, A> +where + T: fmt::Debug, + A: Allocator, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let peek = if self.idx < self.end { self.vec.get(self.idx) } else { None }; + f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive() + } +} diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 9ad26e5d28ec..961d6ee0665c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -683,7 +683,7 @@ impl HashMap { /// ``` #[inline] #[rustc_lint_query_instability] - #[stable(feature = "hash_extract_if", since = "1.87.0")] + #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, @@ -1680,12 +1680,9 @@ impl<'a, K, V> Drain<'a, K, V> { /// ]); /// let iter = map.extract_if(|_k, v| *v % 2 == 0); /// ``` -#[stable(feature = "hash_extract_if", since = "1.87.0")] +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] #[must_use = "iterators are lazy and do nothing unless consumed"] -pub struct ExtractIf<'a, K, V, F> -where - F: FnMut(&K, &mut V) -> bool, -{ +pub struct ExtractIf<'a, K, V, F> { base: base::ExtractIf<'a, K, V, F>, } @@ -2297,7 +2294,7 @@ where } } -#[stable(feature = "hash_extract_if", since = "1.87.0")] +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] impl Iterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, @@ -2314,13 +2311,14 @@ where } } -#[stable(feature = "hash_extract_if", since = "1.87.0")] +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] impl FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} -#[stable(feature = "hash_extract_if", since = "1.87.0")] -impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F> +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Debug for ExtractIf<'_, K, V, F> where - F: FnMut(&K, &mut V) -> bool, + K: fmt::Debug, + V: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ExtractIf").finish_non_exhaustive() diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 7be000594bc5..fa2f4f0a58fe 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -308,7 +308,7 @@ impl HashSet { /// ``` #[inline] #[rustc_lint_query_instability] - #[stable(feature = "hash_extract_if", since = "1.87.0")] + #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F> where F: FnMut(&T) -> bool, @@ -1390,11 +1390,8 @@ pub struct Drain<'a, K: 'a> { /// /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0); /// ``` -#[stable(feature = "hash_extract_if", since = "1.87.0")] -pub struct ExtractIf<'a, K, F> -where - F: FnMut(&K) -> bool, -{ +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +pub struct ExtractIf<'a, K, F> { base: base::ExtractIf<'a, K, F>, } @@ -1673,7 +1670,7 @@ impl fmt::Debug for Drain<'_, K> { } } -#[stable(feature = "hash_extract_if", since = "1.87.0")] +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] impl Iterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool, @@ -1690,13 +1687,13 @@ where } } -#[stable(feature = "hash_extract_if", since = "1.87.0")] +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] impl FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {} -#[stable(feature = "hash_extract_if", since = "1.87.0")] -impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F> +#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Debug for ExtractIf<'_, K, F> where - F: FnMut(&K) -> bool, + K: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ExtractIf").finish_non_exhaustive() diff --git a/tests/rustdoc-js-std/path-maxeditdistance.js b/tests/rustdoc-js-std/path-maxeditdistance.js index fd12a0564966..6989e7d6488b 100644 --- a/tests/rustdoc-js-std/path-maxeditdistance.js +++ b/tests/rustdoc-js-std/path-maxeditdistance.js @@ -13,9 +13,9 @@ const EXPECTED = [ { 'path': 'std::vec', 'name': 'IntoIter' }, { 'path': 'std::vec::Vec', 'name': 'from_iter' }, { 'path': 'std::vec::Vec', 'name': 'into_iter' }, + { 'path': 'std::vec::ExtractIf', 'name': 'into_iter' }, { 'path': 'std::vec::Drain', 'name': 'into_iter' }, { 'path': 'std::vec::IntoIter', 'name': 'into_iter' }, - { 'path': 'std::vec::ExtractIf', 'name': 'into_iter' }, { 'path': 'std::vec::Splice', 'name': 'into_iter' }, { 'path': 'std::collections::VecDeque', 'name': 'iter' }, { 'path': 'std::collections::VecDeque', 'name': 'iter_mut' }, From 9e7fb67838ce06e418d078c4d04b0ff578bd1f43 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 6 May 2025 12:54:03 +1000 Subject: [PATCH 187/262] Rename `graph::implementation::Graph` to `LinkedGraph` --- .../{implementation => linked_graph}/mod.rs | 36 +++++++++++++------ .../{implementation => linked_graph}/tests.rs | 8 ++--- .../rustc_data_structures/src/graph/mod.rs | 2 +- .../rustc_incremental/src/assert_dep_graph.rs | 2 +- .../src/infer/lexical_region_resolve/mod.rs | 8 ++--- .../rustc_query_system/src/dep_graph/query.rs | 6 ++-- 6 files changed, 39 insertions(+), 23 deletions(-) rename compiler/rustc_data_structures/src/graph/{implementation => linked_graph}/mod.rs (88%) rename compiler/rustc_data_structures/src/graph/{implementation => linked_graph}/tests.rs (95%) diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs similarity index 88% rename from compiler/rustc_data_structures/src/graph/implementation/mod.rs rename to compiler/rustc_data_structures/src/graph/linked_graph/mod.rs index a80365938b96..ecb0095626b4 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs +++ b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs @@ -1,4 +1,4 @@ -//! A graph module for use in dataflow, region resolution, and elsewhere. +//! See [`LinkedGraph`]. //! //! # Interface details //! @@ -28,7 +28,23 @@ use tracing::debug; #[cfg(test)] mod tests; -pub struct Graph { +/// A concrete graph implementation that supports: +/// - Nodes and/or edges labelled with custom data types (`N` and `E` respectively). +/// - Incremental addition of new nodes/edges (but not removal). +/// - Flat storage of node/edge data in a pair of vectors. +/// - Iteration over any node's out-edges or in-edges, via linked lists +/// threaded through the node/edge data. +/// +/// # Caution +/// This is an older graph implementation that is still used by some pieces +/// of diagnostic/debugging code. New code that needs a graph data structure +/// should consider using `VecGraph` instead, or implementing its own +/// special-purpose graph with the specific features needed. +/// +/// This graph implementation predates the later [graph traits](crate::graph), +/// and does not implement those traits, so it has its own implementations of a +/// few basic graph algorithms. +pub struct LinkedGraph { nodes: Vec>, edges: Vec>, } @@ -71,13 +87,13 @@ impl NodeIndex { } } -impl Graph { - pub fn new() -> Graph { - Graph { nodes: Vec::new(), edges: Vec::new() } +impl LinkedGraph { + pub fn new() -> Self { + Self { nodes: Vec::new(), edges: Vec::new() } } - pub fn with_capacity(nodes: usize, edges: usize) -> Graph { - Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) } + pub fn with_capacity(nodes: usize, edges: usize) -> Self { + Self { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) } } // # Simple accessors @@ -249,7 +265,7 @@ impl Graph { // # Iterators pub struct AdjacentEdges<'g, N, E> { - graph: &'g Graph, + graph: &'g LinkedGraph, direction: Direction, next: EdgeIndex, } @@ -285,7 +301,7 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { } pub struct DepthFirstTraversal<'g, N, E> { - graph: &'g Graph, + graph: &'g LinkedGraph, stack: Vec, visited: DenseBitSet, direction: Direction, @@ -293,7 +309,7 @@ pub struct DepthFirstTraversal<'g, N, E> { impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> { pub fn with_start_node( - graph: &'g Graph, + graph: &'g LinkedGraph, start_node: NodeIndex, direction: Direction, ) -> Self { diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs similarity index 95% rename from compiler/rustc_data_structures/src/graph/implementation/tests.rs rename to compiler/rustc_data_structures/src/graph/linked_graph/tests.rs index 32a6d9ec881a..357aa81a57ca 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs +++ b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs @@ -1,11 +1,11 @@ use tracing::debug; -use crate::graph::implementation::*; +use super::{Debug, LinkedGraph, NodeIndex}; -type TestGraph = Graph<&'static str, &'static str>; +type TestGraph = LinkedGraph<&'static str, &'static str>; fn create_graph() -> TestGraph { - let mut graph = Graph::new(); + let mut graph = LinkedGraph::new(); // Create a simple graph // @@ -56,7 +56,7 @@ fn each_edge() { } fn test_adjacent_edges( - graph: &Graph, + graph: &LinkedGraph, start_index: NodeIndex, start_data: N, expected_incoming: &[(E, N)], diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 4a1e5db6768d..20416b472b21 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -1,8 +1,8 @@ use rustc_index::Idx; pub mod dominators; -pub mod implementation; pub mod iterate; +pub mod linked_graph; mod reference; pub mod reversed; pub mod scc; diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 1b2056f541f3..0e04a2a784ec 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -38,7 +38,7 @@ use std::fs::{self, File}; use std::io::Write; use rustc_data_structures::fx::FxIndexSet; -use rustc_data_structures::graph::implementation::{Direction, INCOMING, NodeIndex, OUTGOING}; +use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::dep_graph::{ diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index e3522137d838..2185886901e5 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -3,8 +3,8 @@ use std::fmt; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::graph::implementation::{ - Direction, Graph, INCOMING, NodeIndex, OUTGOING, +use rustc_data_structures::graph::linked_graph::{ + Direction, INCOMING, LinkedGraph, NodeIndex, OUTGOING, }; use rustc_data_structures::intern::Interned; use rustc_data_structures::unord::UnordSet; @@ -118,7 +118,7 @@ struct RegionAndOrigin<'tcx> { origin: SubregionOrigin<'tcx>, } -type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>; +type RegionGraph<'tcx> = LinkedGraph<(), Constraint<'tcx>>; struct LexicalResolver<'cx, 'tcx> { region_rels: &'cx RegionRelations<'cx, 'tcx>, @@ -668,7 +668,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn construct_graph(&self) -> RegionGraph<'tcx> { let num_vars = self.num_vars(); - let mut graph = Graph::new(); + let mut graph = LinkedGraph::new(); for _ in 0..num_vars { graph.add_node(()); diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index 624f4e4578ed..724a01327aba 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -1,11 +1,11 @@ use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::graph::implementation::{Direction, Graph, INCOMING, NodeIndex}; +use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, NodeIndex}; use rustc_index::IndexVec; use super::{DepNode, DepNodeIndex}; pub struct DepGraphQuery { - pub graph: Graph, + pub graph: LinkedGraph, pub indices: FxHashMap, pub dep_index_to_index: IndexVec>, } @@ -15,7 +15,7 @@ impl DepGraphQuery { let node_count = prev_node_count + prev_node_count / 4; let edge_count = 6 * node_count; - let graph = Graph::with_capacity(node_count, edge_count); + let graph = LinkedGraph::with_capacity(node_count, edge_count); let indices = FxHashMap::default(); let dep_index_to_index = IndexVec::new(); From cbaa73beca9a7b62c6400669e47e09958e8804ab Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 6 May 2025 02:37:45 +0800 Subject: [PATCH 188/262] tests: don't ignore compiler stderr in `lib-defaults.rs` And also: - Document test intent. - Move under `link-native-libs/` instead. --- tests/ui/abi/lib-defaults.rs | 15 --------------- tests/ui/link-native-libs/lib-defaults.rs | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 15 deletions(-) delete mode 100644 tests/ui/abi/lib-defaults.rs create mode 100644 tests/ui/link-native-libs/lib-defaults.rs diff --git a/tests/ui/abi/lib-defaults.rs b/tests/ui/abi/lib-defaults.rs deleted file mode 100644 index 2c2cad4f82dc..000000000000 --- a/tests/ui/abi/lib-defaults.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass -//@ dont-check-compiler-stderr (rust-lang/rust#54222) - -//@ compile-flags: -lrust_test_helpers - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; -} - -fn main() { - unsafe { - rust_dbg_extern_identity_u32(42); - } -} diff --git a/tests/ui/link-native-libs/lib-defaults.rs b/tests/ui/link-native-libs/lib-defaults.rs new file mode 100644 index 000000000000..4e38adb643db --- /dev/null +++ b/tests/ui/link-native-libs/lib-defaults.rs @@ -0,0 +1,17 @@ +//! By default, `-l NAME` without an explicit kind will default to dylib. However, if there's also +//! an `#[link(name = NAME, kind = KIND)]` attribute with an explicit `KIND`, it should override the +//! CLI flag. In particular, this should not result in any duplicate flag warnings from the linker. + +//@ run-pass +//@ compile-flags: -lrust_test_helpers + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; +} + +fn main() { + unsafe { + rust_dbg_extern_identity_u32(42); + } +} From 3d4737fb5e999ef66e57753e432f7f8076bc5192 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 19 Feb 2025 11:41:31 +0100 Subject: [PATCH 189/262] Remove duplicate impl of string unescape --- compiler/rustc_builtin_macros/src/format.rs | 11 +- compiler/rustc_parse_format/src/lib.rs | 812 +++++++----------- compiler/rustc_parse_format/src/tests.rs | 159 +++- .../traits/on_unimplemented_format.rs | 17 +- .../hir-def/src/expr_store/lower/asm.rs | 2 +- .../crates/hir-def/src/hir/format_args.rs | 4 +- 6 files changed, 453 insertions(+), 552 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 12654001a1e2..39f9d5f90051 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use parse::Position::ArgumentNamed; use rustc_ast::ptr::P; use rustc_ast::tokenstream::TokenStream; @@ -335,7 +337,7 @@ fn make_format_args( return ExpandResult::Ready(Err(guar)); } - let to_span = |inner_span: parse::InnerSpan| { + let to_span = |inner_span: Range| { is_source_literal.then(|| { fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end }) }) @@ -407,7 +409,7 @@ fn make_format_args( let mut placeholder_index = 0; for piece in &pieces { - match *piece { + match piece.clone() { parse::Piece::Lit(s) => { unfinished_literal.push_str(s); } @@ -417,7 +419,8 @@ fn make_format_args( unfinished_literal.clear(); } - let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s)); + let span = + parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone())); placeholder_index += 1; let position_span = to_span(position_span); @@ -609,7 +612,7 @@ fn make_format_args( fn invalid_placeholder_type_error( ecx: &ExtCtxt<'_>, ty: &str, - ty_span: Option, + ty_span: Option>, fmt_span: Span, ) { let sp = ty_span.map(|sp| fmt_span.from_inner(InnerSpan::new(sp.start, sp.end))); diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 999e71592745..9dd064aca662 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -15,50 +15,13 @@ )] // tidy-alphabetical-end +use std::ops::Range; + pub use Alignment::*; pub use Count::*; pub use Position::*; use rustc_literal_escaper::{Mode, unescape_unicode}; -// Note: copied from rustc_span -/// Range inside of a `Span` used for diagnostics when we only have access to relative positions. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct InnerSpan { - pub start: usize, - pub end: usize, -} - -impl InnerSpan { - pub fn new(start: usize, end: usize) -> InnerSpan { - InnerSpan { start, end } - } -} - -/// The location and before/after width of a character whose width has changed from its source code -/// representation -#[derive(Copy, Clone, PartialEq, Eq)] -pub struct InnerWidthMapping { - /// Index of the character in the source - pub position: usize, - /// The inner width in characters - pub before: usize, - /// The transformed width in characters - pub after: usize, -} - -impl InnerWidthMapping { - pub fn new(position: usize, before: usize, after: usize) -> InnerWidthMapping { - InnerWidthMapping { position, before, after } - } -} - -/// Whether the input string is a literal. If yes, it contains the inner width mappings. -#[derive(Clone, PartialEq, Eq)] -enum InputStringKind { - NotALiteral, - Literal { width_mappings: Vec }, -} - /// The type of format string that we are parsing. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum ParseMode { @@ -68,15 +31,6 @@ pub enum ParseMode { InlineAsm, } -#[derive(Copy, Clone)] -struct InnerOffset(usize); - -impl InnerOffset { - fn to(self, end: InnerOffset) -> InnerSpan { - InnerSpan::new(self.0, end.0) - } -} - /// A piece is a portion of the format string which represents the next part /// to emit. These are emitted as a stream by the `Parser` class. #[derive(Clone, Debug, PartialEq)] @@ -89,13 +43,13 @@ pub enum Piece<'a> { } /// Representation of an argument specification. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct Argument<'a> { /// Where to find this argument pub position: Position<'a>, /// The span of the position indicator. Includes any whitespace in implicit /// positions (`{ }`). - pub position_span: InnerSpan, + pub position_span: Range, /// How to format the argument pub format: FormatSpec<'a>, } @@ -125,12 +79,12 @@ impl<'a> Argument<'a> { } /// Specification for the formatting of an argument in the format string. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct FormatSpec<'a> { /// Optionally specified character to fill alignment with. pub fill: Option, /// Span of the optionally specified fill character. - pub fill_span: Option, + pub fill_span: Option>, /// Optionally specified alignment. pub align: Alignment, /// The `+` or `-` flag. @@ -144,21 +98,21 @@ pub struct FormatSpec<'a> { /// The integer precision to use. pub precision: Count<'a>, /// The span of the precision formatting flag (for diagnostics). - pub precision_span: Option, + pub precision_span: Option>, /// The string width requested for the resulting format. pub width: Count<'a>, /// The span of the width formatting flag (for diagnostics). - pub width_span: Option, + pub width_span: Option>, /// The descriptor string representing the name of the format desired for /// this argument, this can be empty or any number of characters, although /// it is required to be one word. pub ty: &'a str, /// The span of the descriptor string (for diagnostics). - pub ty_span: Option, + pub ty_span: Option>, } /// Enum describing where an argument for a format can be located. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub enum Position<'a> { /// The argument is implied to be located at an index ArgumentImplicitlyIs(usize), @@ -210,12 +164,12 @@ pub enum DebugHex { /// A count is used for the precision and width parameters of an integer, and /// can reference either an argument or a literal integer. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub enum Count<'a> { /// The count is specified explicitly. CountIs(u16), /// The count is specified by the argument with the given name. - CountIsName(&'a str, InnerSpan), + CountIsName(&'a str, Range), /// The count is specified by the argument at the given index. CountIsParam(usize), /// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index. @@ -228,8 +182,8 @@ pub struct ParseError { pub description: String, pub note: Option, pub label: String, - pub span: InnerSpan, - pub secondary_label: Option<(String, InnerSpan)>, + pub span: Range, + pub secondary_label: Option<(String, Range)>, pub suggestion: Suggestion, } @@ -240,12 +194,12 @@ pub enum Suggestion { UsePositional, /// Remove `r#` from identifier: /// `format!("{r#foo}")` -> `format!("{foo}")` - RemoveRawIdent(InnerSpan), + RemoveRawIdent(Range), /// Reorder format parameter: /// `format!("{foo:?#}")` -> `format!("{foo:#?}")` /// `format!("{foo:?x}")` -> `format!("{foo:x?}")` /// `format!("{foo:?X}")` -> `format!("{foo:X?}")` - ReorderFormatParameter(InnerSpan, String), + ReorderFormatParameter(Range, String), } /// The parser structure for interpreting the input format string. This is @@ -256,92 +210,94 @@ pub enum Suggestion { /// necessary there's probably lots of room for improvement performance-wise. pub struct Parser<'a> { mode: ParseMode, + /// Input to be parsed input: &'a str, - cur: std::iter::Peekable>, + /// Tuples of the span in the code snippet (input as written before being unescaped), the pos in input, and the char in input + input_vec: Vec<(Range, usize, char)>, + /// Index into input_vec + input_vec_index: usize, /// Error messages accumulated during parsing pub errors: Vec, /// Current position of implicit positional argument pointer pub curarg: usize, - /// `Some(raw count)` when the string is "raw", used to position spans correctly - style: Option, /// Start and end byte offset of every successfully parsed argument - pub arg_places: Vec, - /// Characters whose length has been changed from their in-code representation - width_map: Vec, + pub arg_places: Vec>, /// Span of the last opening brace seen, used for error reporting - last_opening_brace: Option, - /// Whether the source string is comes from `println!` as opposed to `format!` or `print!` - append_newline: bool, + last_open_brace: Option>, /// Whether this formatting string was written directly in the source. This controls whether we /// can use spans to refer into it and give better error messages. /// N.B: This does _not_ control whether implicit argument captures can be used. pub is_source_literal: bool, + /// Index to the end of the literal snippet + end_of_snippet: usize, /// Start position of the current line. cur_line_start: usize, /// Start and end byte offset of every line of the format string. Excludes /// newline characters and leading whitespace. - pub line_spans: Vec, + pub line_spans: Vec>, } impl<'a> Iterator for Parser<'a> { type Item = Piece<'a>; fn next(&mut self) -> Option> { - if let Some(&(pos, c)) = self.cur.peek() { - match c { + if let Some(&(Range { start, end }, idx, ch)) = self.input_vec.get(self.input_vec_index) { + match ch { '{' => { - let curr_last_brace = self.last_opening_brace; - let byte_pos = self.to_span_index(pos); - let lbrace_end = InnerOffset(byte_pos.0 + self.to_span_width(pos)); - self.last_opening_brace = Some(byte_pos.to(lbrace_end)); - self.cur.next(); - if self.consume('{') { - self.last_opening_brace = curr_last_brace; - - Some(Piece::Lit(self.string(pos + 1))) + self.input_vec_index += 1; + if let Some(&(_, i, '{')) = self.input_vec.get(self.input_vec_index) { + self.input_vec_index += 1; + // double open brace escape: "{{" + // next state after this is either end-of-input or seen-a-brace + Some(Piece::Lit(self.string(i))) } else { - let arg = self.argument(lbrace_end); - if let Some(rbrace_pos) = self.consume_closing_brace(&arg) { + // single open brace + self.last_open_brace = Some(start..end); + let arg = self.argument(); + if let Some(close_brace_range) = self.consume_closing_brace(&arg) { if self.is_source_literal { - let lbrace_byte_pos = self.to_span_index(pos); - let rbrace_byte_pos = self.to_span_index(rbrace_pos); - - let width = self.to_span_width(rbrace_pos); - - self.arg_places.push( - lbrace_byte_pos.to(InnerOffset(rbrace_byte_pos.0 + width)), - ); + self.arg_places.push(start..close_brace_range.end); } - } else if let Some(&(_, maybe)) = self.cur.peek() { - match maybe { + } else if let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) { + match c { '?' => self.suggest_format_debug(), - '<' | '^' | '>' => self.suggest_format_align(maybe), - _ => self.suggest_positional_arg_instead_of_captured_arg(arg), + '<' | '^' | '>' => self.suggest_format_align(c), + _ => { + self.suggest_positional_arg_instead_of_captured_arg(arg.clone()) + } } } Some(Piece::NextArgument(Box::new(arg))) } } '}' => { - self.cur.next(); - if self.consume('}') { - Some(Piece::Lit(self.string(pos + 1))) + self.input_vec_index += 1; + if let Some(&(_, i, '}')) = self.input_vec.get(self.input_vec_index) { + self.input_vec_index += 1; + // double close brace escape: "}}" + // next state after this is either end-of-input or start + Some(Piece::Lit(self.string(i))) } else { - let err_pos = self.to_span_index(pos); - self.err_with_note( - "unmatched `}` found", - "unmatched `}`", - "if you intended to print `}`, you can escape it using `}}`", - err_pos.to(err_pos), - ); + // error: single close brace without corresponding open brace + self.errors.push(ParseError { + description: "unmatched `}` found".into(), + note: Some( + "if you intended to print `}`, you can escape it using `}}`".into(), + ), + label: "unmatched `}`".into(), + span: start..end, + secondary_label: None, + suggestion: Suggestion::None, + }); None } } - _ => Some(Piece::Lit(self.string(pos))), + _ => Some(Piece::Lit(self.string(idx))), } } else { + // end of input if self.is_source_literal { - let span = self.span(self.cur_line_start, self.input.len()); + let span = self.cur_line_start..self.end_of_snippet; if self.line_spans.last() != Some(&span) { self.line_spans.push(span); } @@ -352,71 +308,104 @@ impl<'a> Iterator for Parser<'a> { } impl<'a> Parser<'a> { - /// Creates a new parser for the given format string + /// Creates a new parser for the given unescaped input string and + /// optional code snippet (the input as written before being unescaped), + /// where `style` is `Some(nr_hashes)` when the snippet is a raw string with that many hashes. + /// If the input comes via `println` or `panic`, then it has a newline already appended, + /// which is reflected in the `appended_newline` parameter. pub fn new( - s: &'a str, + input: &'a str, style: Option, snippet: Option, - append_newline: bool, + appended_newline: bool, mode: ParseMode, - ) -> Parser<'a> { - let input_string_kind = find_width_map_from_snippet(s, snippet, style); - let (width_map, is_source_literal) = match input_string_kind { - InputStringKind::Literal { width_mappings } => (width_mappings, true), - InputStringKind::NotALiteral => (Vec::new(), false), + ) -> Self { + let quote_offset = style.map_or(1, |nr_hashes| nr_hashes + 2); + + let (is_source_literal, end_of_snippet, pre_input_vec) = if let Some(snippet) = snippet { + if let Some(nr_hashes) = style { + // snippet is a raw string, which starts with 'r', a number of hashes, and a quote + // and ends with a quote and the same number of hashes + (true, snippet.len() - nr_hashes - 1, vec![]) + } else { + // snippet is not a raw string + if snippet.starts_with('"') { + // snippet looks like an ordinary string literal + // check whether it is the escaped version of input + let without_quotes = &snippet[1..snippet.len() - 1]; + let (mut ok, mut vec) = (true, vec![]); + let mut chars = input.chars(); + unescape_unicode(without_quotes, Mode::Str, &mut |range, res| match res { + Ok(ch) if ok && chars.next().is_some_and(|c| ch == c) => { + vec.push((range, ch)); + } + _ => { + ok = false; + vec = vec![]; + } + }); + let end = vec.last().map(|(r, _)| r.end).unwrap_or(0); + if ok { + if appended_newline { + if chars.as_str() == "\n" { + vec.push((end..end + 1, '\n')); + (true, 1 + end, vec) + } else { + (false, snippet.len(), vec![]) + } + } else if chars.as_str() == "" { + (true, 1 + end, vec) + } else { + (false, snippet.len(), vec![]) + } + } else { + (false, snippet.len(), vec![]) + } + } else { + // snippet is not a raw string and does not start with '"' + (false, snippet.len(), vec![]) + } + } + } else { + // snippet is None + (false, input.len() - if appended_newline { 1 } else { 0 }, vec![]) + }; + + let input_vec: Vec<(Range, usize, char)> = if pre_input_vec.is_empty() { + // Snippet is *not* input before unescaping, so spans pointing at it will be incorrect. + // This can happen with proc macros that respan generated literals. + input + .char_indices() + .map(|(idx, c)| { + let i = idx + quote_offset; + (i..i + c.len_utf8(), idx, c) + }) + .collect() + } else { + // Snippet is input before unescaping + input + .char_indices() + .zip(pre_input_vec) + .map(|((i, c), (r, _))| (r.start + quote_offset..r.end + quote_offset, i, c)) + .collect() }; Parser { mode, - input: s, - cur: s.char_indices().peekable(), + input, + input_vec, + input_vec_index: 0, errors: vec![], curarg: 0, - style, arg_places: vec![], - width_map, - last_opening_brace: None, - append_newline, + last_open_brace: None, is_source_literal, - cur_line_start: 0, + end_of_snippet, + cur_line_start: quote_offset, line_spans: vec![], } } - /// Notifies of an error. The message doesn't actually need to be of type - /// String, but I think it does when this eventually uses conditions so it - /// might as well start using it now. - fn err(&mut self, description: impl Into, label: impl Into, span: InnerSpan) { - self.errors.push(ParseError { - description: description.into(), - note: None, - label: label.into(), - span, - secondary_label: None, - suggestion: Suggestion::None, - }); - } - - /// Notifies of an error. The message doesn't actually need to be of type - /// String, but I think it does when this eventually uses conditions so it - /// might as well start using it now. - fn err_with_note( - &mut self, - description: impl Into, - label: impl Into, - note: impl Into, - span: InnerSpan, - ) { - self.errors.push(ParseError { - description: description.into(), - note: Some(note.into()), - label: label.into(), - span, - secondary_label: None, - suggestion: Suggestion::None, - }); - } - /// Optionally consumes the specified character. If the character is not at /// the current position, then the current iterator isn't moved and `false` is /// returned, otherwise the character is consumed and `true` is returned. @@ -428,94 +417,56 @@ impl<'a> Parser<'a> { /// the current position, then the current iterator isn't moved and `None` is /// returned, otherwise the character is consumed and the current position is /// returned. - fn consume_pos(&mut self, c: char) -> Option { - if let Some(&(pos, maybe)) = self.cur.peek() { - if c == maybe { - self.cur.next(); - return Some(pos); + fn consume_pos(&mut self, ch: char) -> Option<(Range, usize)> { + if let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) { + if ch == *c { + self.input_vec_index += 1; + return Some((r.clone(), *i)); } } None } - fn remap_pos(&self, mut pos: usize) -> InnerOffset { - for width in &self.width_map { - if pos > width.position { - pos += width.before - width.after; - } else if pos == width.position && width.after == 0 { - pos += width.before; - } else { - break; - } - } - - InnerOffset(pos) - } - - fn to_span_index(&self, pos: usize) -> InnerOffset { - // This handles the raw string case, the raw argument is the number of # - // in r###"..."### (we need to add one because of the `r`). - let raw = self.style.map_or(0, |raw| raw + 1); - let pos = self.remap_pos(pos); - InnerOffset(raw + pos.0 + 1) - } - - fn to_span_width(&self, pos: usize) -> usize { - let pos = self.remap_pos(pos); - match self.width_map.iter().find(|w| w.position == pos.0) { - Some(w) => w.before, - None => 1, - } - } - - fn span(&self, start_pos: usize, end_pos: usize) -> InnerSpan { - let start = self.to_span_index(start_pos); - let end = self.to_span_index(end_pos); - start.to(end) - } - /// Forces consumption of the specified character. If the character is not /// found, an error is emitted. - fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option { + fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option> { self.ws(); - let pos; - let description; - - if let Some(&(peek_pos, maybe)) = self.cur.peek() { - if maybe == '}' { - self.cur.next(); - return Some(peek_pos); + let (range, description) = if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) + { + if *c == '}' { + self.input_vec_index += 1; + return Some(r.clone()); } - - pos = peek_pos; - description = format!("expected `}}`, found `{}`", maybe.escape_debug()); + // or r.clone()? + (r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug())) } else { - description = "expected `}` but string was terminated".to_owned(); - // point at closing `"` - pos = self.input.len() - if self.append_newline { 1 } else { 0 }; - } + ( + // point at closing `"` + self.end_of_snippet..self.end_of_snippet, + "expected `}` but string was terminated".to_owned(), + ) + }; - let pos = self.to_span_index(pos); - - let label = "expected `}`".to_owned(); let (note, secondary_label) = if arg.format.fill == Some('}') { ( Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()), - arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)), + arg.format.fill_span.clone().map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)), ) } else { ( Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), - self.last_opening_brace.map(|sp| ("because of this opening brace".to_owned(), sp)), + self.last_open_brace + .clone() + .map(|sp| ("because of this opening brace".to_owned(), sp)), ) }; self.errors.push(ParseError { description, note, - label, - span: pos.to(pos), + label: "expected `}`".to_owned(), + span: range.start..range.start, secondary_label, suggestion: Suggestion::None, }); @@ -525,28 +476,30 @@ impl<'a> Parser<'a> { /// Consumes all whitespace characters until the first non-whitespace character fn ws(&mut self) { - while let Some(_) = self.cur.next_if(|&(_, c)| c.is_whitespace()) {} + let rest = &self.input_vec[self.input_vec_index..]; + let step = rest.iter().position(|&(_, _, c)| !c.is_whitespace()).unwrap_or(rest.len()); + self.input_vec_index += step; } /// Parses all of a string which is to be considered a "raw literal" in a /// format string. This is everything outside of the braces. fn string(&mut self, start: usize) -> &'a str { - // we may not consume the character, peek the iterator - while let Some(&(pos, c)) = self.cur.peek() { + while let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) { match c { '{' | '}' => { - return &self.input[start..pos]; + return &self.input[start..*i]; } '\n' if self.is_source_literal => { - self.line_spans.push(self.span(self.cur_line_start, pos)); - self.cur_line_start = pos + 1; - self.cur.next(); + self.input_vec_index += 1; + self.line_spans.push(self.cur_line_start..r.start); + self.cur_line_start = r.end; } _ => { - if self.is_source_literal && pos == self.cur_line_start && c.is_whitespace() { - self.cur_line_start = pos + c.len_utf8(); + self.input_vec_index += 1; + if self.is_source_literal && r.start == self.cur_line_start && c.is_whitespace() + { + self.cur_line_start = r.end; } - self.cur.next(); } } } @@ -554,15 +507,13 @@ impl<'a> Parser<'a> { } /// Parses an `Argument` structure, or what's contained within braces inside the format string. - fn argument(&mut self, start: InnerOffset) -> Argument<'a> { - let pos = self.position(); + fn argument(&mut self) -> Argument<'a> { + let start_idx = self.input_vec_index; - let end = self - .cur - .clone() - .find(|(_, ch)| !ch.is_whitespace()) - .map_or(start, |(end, _)| self.to_span_index(end)); - let position_span = start.to(end); + let position = self.position(); + self.ws(); + + let end_idx = self.input_vec_index; let format = match self.mode { ParseMode::Format => self.format(), @@ -570,16 +521,15 @@ impl<'a> Parser<'a> { }; // Resolve position after parsing format spec. - let pos = match pos { - Some(position) => position, - None => { - let i = self.curarg; - self.curarg += 1; - ArgumentImplicitlyIs(i) - } - }; + let position = position.unwrap_or_else(|| { + let i = self.curarg; + self.curarg += 1; + ArgumentImplicitlyIs(i) + }); - Argument { position: pos, position_span, format } + let position_span = + self.input_vec_index2range(start_idx).start..self.input_vec_index2range(end_idx).start; + Argument { position, position_span, format } } /// Parses a positional argument for a format. This could either be an @@ -590,23 +540,26 @@ impl<'a> Parser<'a> { if let Some(i) = self.integer() { Some(ArgumentIs(i.into())) } else { - match self.cur.peek() { - Some(&(lo, c)) if rustc_lexer::is_id_start(c) => { + match self.input_vec.get(self.input_vec_index) { + Some((range, _, c)) if rustc_lexer::is_id_start(*c) => { + let start = range.start; let word = self.word(); // Recover from `r#ident` in format strings. // FIXME: use a let chain if word == "r" { - if let Some((pos, '#')) = self.cur.peek() { - if self.input[pos + 1..] - .chars() - .next() - .is_some_and(rustc_lexer::is_id_start) + if let Some((r, _, '#')) = self.input_vec.get(self.input_vec_index) { + if self + .input_vec + .get(self.input_vec_index + 1) + .is_some_and(|(_, _, c)| rustc_lexer::is_id_start(*c)) { - self.cur.next(); + self.input_vec_index += 1; + let prefix_end = r.end; let word = self.word(); - let prefix_span = self.span(lo, lo + 2); - let full_span = self.span(lo, lo + 2 + word.len()); + let prefix_span = start..prefix_end; + let full_span = + start..self.input_vec_index2range(self.input_vec_index).start; self.errors.insert(0, ParseError { description: "raw identifiers are not supported".to_owned(), note: Some("identifiers in format strings can be keywords and don't need to be prefixed with `r#`".to_string()), @@ -622,7 +575,6 @@ impl<'a> Parser<'a> { Some(ArgumentNamed(word)) } - // This is an `ArgumentNext`. // Record the fact and do the resolution after parsing the // format spec, to make things like `{:.*}` work. @@ -631,8 +583,16 @@ impl<'a> Parser<'a> { } } - fn current_pos(&mut self) -> usize { - if let Some(&(pos, _)) = self.cur.peek() { pos } else { self.input.len() } + fn input_vec_index2pos(&self, index: usize) -> usize { + if let Some(&(_, pos, _)) = self.input_vec.get(index) { pos } else { self.input.len() } + } + + fn input_vec_index2range(&self, index: usize) -> Range { + if let Some((r, _, _)) = self.input_vec.get(index) { + r.clone() + } else { + self.end_of_snippet..self.end_of_snippet + } } /// Parses a format specifier at the current position, returning all of the @@ -658,11 +618,11 @@ impl<'a> Parser<'a> { } // fill character - if let Some(&(idx, c)) = self.cur.peek() { - if let Some((_, '>' | '<' | '^')) = self.cur.clone().nth(1) { + if let Some(&(ref r, _, c)) = self.input_vec.get(self.input_vec_index) { + if let Some((_, _, '>' | '<' | '^')) = self.input_vec.get(self.input_vec_index + 1) { + self.input_vec_index += 1; spec.fill = Some(c); - spec.fill_span = Some(self.span(idx, idx + 1)); - self.cur.next(); + spec.fill_span = Some(r.clone()); } } // Alignment @@ -686,14 +646,14 @@ impl<'a> Parser<'a> { // Width and precision let mut havewidth = false; - if self.consume('0') { + if let Some((range, _)) = self.consume_pos('0') { // small ambiguity with '0$' as a format string. In theory this is a // '0' flag and then an ill-formatted format string with just a '$' // and no count, but this is better if we instead interpret this as // no '0' flag and '0$' as the width instead. - if let Some(end) = self.consume_pos('$') { + if let Some((r, _)) = self.consume_pos('$') { spec.width = CountIsParam(0); - spec.width_span = Some(self.span(end - 1, end + 1)); + spec.width_span = Some(range.start..r.end); havewidth = true; } else { spec.zero_pad = true; @@ -701,15 +661,15 @@ impl<'a> Parser<'a> { } if !havewidth { - let start = self.current_pos(); - spec.width = self.count(start); + let start_idx = self.input_vec_index; + spec.width = self.count(); if spec.width != CountImplied { - let end = self.current_pos(); - spec.width_span = Some(self.span(start, end)); + let end = self.input_vec_index2range(self.input_vec_index).start; + spec.width_span = Some(self.input_vec_index2range(start_idx).start..end); } } - if let Some(start) = self.consume_pos('.') { + if let Some((range, _)) = self.consume_pos('.') { if self.consume('*') { // Resolve `CountIsNextParam`. // We can do this immediately as `position` is resolved later. @@ -717,13 +677,13 @@ impl<'a> Parser<'a> { self.curarg += 1; spec.precision = CountIsStar(i); } else { - spec.precision = self.count(start + 1); + spec.precision = self.count(); } - let end = self.current_pos(); - spec.precision_span = Some(self.span(start, end)); + spec.precision_span = + Some(range.start..self.input_vec_index2range(self.input_vec_index).start); } - let ty_span_start = self.current_pos(); + let start_idx = self.input_vec_index; // Optional radix followed by the actual format specifier if self.consume('x') { if self.consume('?') { @@ -739,19 +699,33 @@ impl<'a> Parser<'a> { } else { spec.ty = "X"; } - } else if self.consume('?') { + } else if let Some((range, _)) = self.consume_pos('?') { spec.ty = "?"; - if let Some(&(_, maybe)) = self.cur.peek() { - match maybe { - '#' | 'x' | 'X' => self.suggest_format_parameter(maybe), + if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) { + match c { + '#' | 'x' | 'X' => self.errors.insert( + 0, + ParseError { + description: format!("expected `}}`, found `{c}`"), + note: None, + label: "expected `'}'`".into(), + span: r.clone(), + secondary_label: None, + suggestion: Suggestion::ReorderFormatParameter( + range.start..r.end, + format!("{c}?"), + ), + }, + ), _ => (), } } } else { spec.ty = self.word(); if !spec.ty.is_empty() { - let ty_span_end = self.current_pos(); - spec.ty_span = Some(self.span(ty_span_start, ty_span_end)); + let start = self.input_vec_index2range(start_idx).start; + let end = self.input_vec_index2range(self.input_vec_index).start; + spec.ty_span = Some(start..end); } } spec @@ -779,11 +753,12 @@ impl<'a> Parser<'a> { return spec; } - let ty_span_start = self.current_pos(); + let start_idx = self.input_vec_index; spec.ty = self.word(); if !spec.ty.is_empty() { - let ty_span_end = self.current_pos(); - spec.ty_span = Some(self.span(ty_span_start, ty_span_end)); + let start = self.input_vec_index2range(start_idx).start; + let end = self.input_vec_index2range(self.input_vec_index).start; + spec.ty_span = Some(start..end); } spec @@ -792,55 +767,58 @@ impl<'a> Parser<'a> { /// Parses a `Count` parameter at the current position. This does not check /// for 'CountIsNextParam' because that is only used in precision, not /// width. - fn count(&mut self, start: usize) -> Count<'a> { + fn count(&mut self) -> Count<'a> { if let Some(i) = self.integer() { if self.consume('$') { CountIsParam(i.into()) } else { CountIs(i) } } else { - let tmp = self.cur.clone(); + let start_idx = self.input_vec_index; let word = self.word(); if word.is_empty() { - self.cur = tmp; CountImplied - } else if let Some(end) = self.consume_pos('$') { - let name_span = self.span(start, end); - CountIsName(word, name_span) + } else if let Some((r, _)) = self.consume_pos('$') { + CountIsName(word, self.input_vec_index2range(start_idx).start..r.start) } else { - self.cur = tmp; + self.input_vec_index = start_idx; CountImplied } } } - /// Parses a word starting at the current position. A word is the same as + /// Parses a word starting at the current position. A word is the same as a /// Rust identifier, except that it can't start with `_` character. fn word(&mut self) -> &'a str { - let start = match self.cur.peek() { - Some(&(pos, c)) if rustc_lexer::is_id_start(c) => { - self.cur.next(); - pos + let index = self.input_vec_index; + match self.input_vec.get(self.input_vec_index) { + Some(&(ref r, i, c)) if rustc_lexer::is_id_start(c) => { + self.input_vec_index += 1; + (r.start, i) } _ => { return ""; } }; - let mut end = None; - while let Some(&(pos, c)) = self.cur.peek() { - if rustc_lexer::is_id_continue(c) { - self.cur.next(); + let (err_end, end): (usize, usize) = loop { + if let Some(&(ref r, i, c)) = self.input_vec.get(self.input_vec_index) { + if rustc_lexer::is_id_continue(c) { + self.input_vec_index += 1; + } else { + break (r.start, i); + } } else { - end = Some(pos); - break; + break (self.end_of_snippet, self.input.len()); } - } - let end = end.unwrap_or(self.input.len()); - let word = &self.input[start..end]; + }; + + let word = &self.input[self.input_vec_index2pos(index)..end]; if word == "_" { - self.err_with_note( - "invalid argument name `_`", - "invalid argument name", - "argument name cannot be a single underscore", - self.span(start, end), - ); + self.errors.push(ParseError { + description: "invalid argument name `_`".into(), + note: Some("argument name cannot be a single underscore".into()), + label: "invalid argument name".into(), + span: self.input_vec_index2range(index).start..err_end, + secondary_label: None, + suggestion: Suggestion::None, + }); } word } @@ -849,9 +827,10 @@ impl<'a> Parser<'a> { let mut cur: u16 = 0; let mut found = false; let mut overflow = false; - let start = self.current_pos(); - while let Some(&(_, c)) = self.cur.peek() { + let start_index = self.input_vec_index; + while let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) { if let Some(i) = c.to_digit(10) { + self.input_vec_index += 1; let (tmp, mul_overflow) = cur.overflowing_mul(10); let (tmp, add_overflow) = tmp.overflowing_add(i as u16); if mul_overflow || add_overflow { @@ -859,40 +838,42 @@ impl<'a> Parser<'a> { } cur = tmp; found = true; - self.cur.next(); } else { break; } } if overflow { - let end = self.current_pos(); - let overflowed_int = &self.input[start..end]; - self.err( - format!( + let overflowed_int = &self.input[self.input_vec_index2pos(start_index) + ..self.input_vec_index2pos(self.input_vec_index)]; + self.errors.push(ParseError { + description: format!( "integer `{}` does not fit into the type `u16` whose range is `0..={}`", overflowed_int, u16::MAX ), - "integer out of range for `u16`", - self.span(start, end), - ); + note: None, + label: "integer out of range for `u16`".into(), + span: self.input_vec_index2range(start_index).start + ..self.input_vec_index2range(self.input_vec_index).end, + secondary_label: None, + suggestion: Suggestion::None, + }); } found.then_some(cur) } fn suggest_format_debug(&mut self) { - if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) { + if let (Some((range, _)), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) { let word = self.word(); - let pos = self.to_span_index(pos); self.errors.insert( 0, ParseError { description: "expected format parameter to occur after `:`".to_owned(), note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")), label: "expected `?` to occur after `:`".to_owned(), - span: pos.to(pos), + span: range, secondary_label: None, suggestion: Suggestion::None, }, @@ -901,15 +882,14 @@ impl<'a> Parser<'a> { } fn suggest_format_align(&mut self, alignment: char) { - if let Some(pos) = self.consume_pos(alignment) { - let pos = self.to_span_index(pos); + if let Some((range, _)) = self.consume_pos(alignment) { self.errors.insert( 0, ParseError { description: "expected format parameter to occur after `:`".to_owned(), note: None, label: format!("expected `{}` to occur after `:`", alignment), - span: pos.to(pos), + span: range, secondary_label: None, suggestion: Suggestion::None, }, @@ -923,10 +903,8 @@ impl<'a> Parser<'a> { return; } - if let Some(end) = self.consume_pos('.') { - let byte_pos = self.to_span_index(end); - let start = InnerOffset(byte_pos.0 + 1); - let field = self.argument(start); + if let Some((_range, _pos)) = self.consume_pos('.') { + let field = self.argument(); // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any // deeper nesting, or another type of expression, like method calls, are not supported if !self.consume('}') { @@ -941,10 +919,7 @@ impl<'a> Parser<'a> { description: "field access isn't supported".to_string(), note: None, label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), + span: arg.position_span.start..field.position_span.end, secondary_label: None, suggestion: Suggestion::UsePositional, }, @@ -957,10 +932,7 @@ impl<'a> Parser<'a> { description: "tuple index access isn't supported".to_string(), note: None, label: "not supported".to_string(), - span: InnerSpan::new( - arg.position_span.start, - field.position_span.end, - ), + span: arg.position_span.start..field.position_span.end, secondary_label: None, suggestion: Suggestion::UsePositional, }, @@ -971,164 +943,6 @@ impl<'a> Parser<'a> { } } } - - fn suggest_format_parameter(&mut self, c: char) { - let replacement = match c { - '#' => "#?", - 'x' => "x?", - 'X' => "X?", - _ => return, - }; - let Some(pos) = self.consume_pos(c) else { - return; - }; - - let span = self.span(pos - 1, pos + 1); - let pos = self.to_span_index(pos); - - self.errors.insert( - 0, - ParseError { - description: format!("expected `}}`, found `{c}`"), - note: None, - label: "expected `'}'`".into(), - span: pos.to(pos), - secondary_label: None, - suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")), - }, - ) - } -} - -/// Finds the indices of all characters that have been processed and differ between the actual -/// written code (code snippet) and the `InternedString` that gets processed in the `Parser` -/// in order to properly synthesise the intra-string `Span`s for error diagnostics. -fn find_width_map_from_snippet( - input: &str, - snippet: Option, - str_style: Option, -) -> InputStringKind { - let snippet = match snippet { - Some(ref s) if s.starts_with('"') || s.starts_with("r\"") || s.starts_with("r#") => s, - _ => return InputStringKind::NotALiteral, - }; - - if str_style.is_some() { - return InputStringKind::Literal { width_mappings: Vec::new() }; - } - - // Strip quotes. - let snippet = &snippet[1..snippet.len() - 1]; - - // Macros like `println` add a newline at the end. That technically doesn't make them "literals" anymore, but it's fine - // since we will never need to point our spans there, so we lie about it here by ignoring it. - // Since there might actually be newlines in the source code, we need to normalize away all trailing newlines. - // If we only trimmed it off the input, `format!("\n")` would cause a mismatch as here we they actually match up. - // Alternatively, we could just count the trailing newlines and only trim one from the input if they don't match up. - let input_no_nl = input.trim_end_matches('\n'); - let Some(unescaped) = unescape_string(snippet) else { - return InputStringKind::NotALiteral; - }; - - let unescaped_no_nl = unescaped.trim_end_matches('\n'); - - if unescaped_no_nl != input_no_nl { - // The source string that we're pointing at isn't our input, so spans pointing at it will be incorrect. - // This can for example happen with proc macros that respan generated literals. - return InputStringKind::NotALiteral; - } - - let mut s = snippet.char_indices(); - let mut width_mappings = vec![]; - while let Some((pos, c)) = s.next() { - match (c, s.clone().next()) { - // skip whitespace and empty lines ending in '\\' - ('\\', Some((_, '\n'))) => { - let _ = s.next(); - let mut width = 2; - - while let Some((_, c)) = s.clone().next() { - if matches!(c, ' ' | '\n' | '\t') { - width += 1; - let _ = s.next(); - } else { - break; - } - } - - width_mappings.push(InnerWidthMapping::new(pos, width, 0)); - } - ('\\', Some((_, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => { - width_mappings.push(InnerWidthMapping::new(pos, 2, 1)); - let _ = s.next(); - } - ('\\', Some((_, 'x'))) => { - // consume `\xAB` literal - s.nth(2); - width_mappings.push(InnerWidthMapping::new(pos, 4, 1)); - } - ('\\', Some((_, 'u'))) => { - let mut width = 2; - let _ = s.next(); - - if let Some((_, next_c)) = s.next() { - if next_c == '{' { - // consume up to 6 hexanumeric chars - let digits_len = - s.clone().take(6).take_while(|(_, c)| c.is_ascii_hexdigit()).count(); - - let len_utf8 = s - .as_str() - .get(..digits_len) - .and_then(|digits| u32::from_str_radix(digits, 16).ok()) - .and_then(char::from_u32) - .map_or(1, char::len_utf8); - - // Skip the digits, for chars that encode to more than 1 utf-8 byte - // exclude as many digits as it is greater than 1 byte - // - // So for a 3 byte character, exclude 2 digits - let required_skips = digits_len.saturating_sub(len_utf8.saturating_sub(1)); - - // skip '{' and '}' also - width += required_skips + 2; - - s.nth(digits_len); - } else if next_c.is_ascii_hexdigit() { - width += 1; - - // We suggest adding `{` and `}` when appropriate, accept it here as if - // it were correct - let mut i = 0; // consume up to 6 hexanumeric chars - while let (Some((_, c)), _) = (s.next(), i < 6) { - if c.is_ascii_hexdigit() { - width += 1; - } else { - break; - } - i += 1; - } - } - } - - width_mappings.push(InnerWidthMapping::new(pos, width, 1)); - } - _ => {} - } - } - - InputStringKind::Literal { width_mappings } -} - -fn unescape_string(string: &str) -> Option { - let mut buf = String::new(); - let mut ok = true; - unescape_unicode(string, Mode::Str, &mut |_, unescaped_char| match unescaped_char { - Ok(c) => buf.push(c), - Err(_) => ok = false, - }); - - ok.then_some(buf) } // Assert a reasonable size for `Piece` diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index cc8a0069c4ec..e6a7f24034ad 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -41,7 +41,6 @@ fn simple() { same("}}", &[Lit("}")]); same("\\}}", &[Lit("\\"), Lit("}")]); } - #[test] fn invalid01() { musterr("{") @@ -79,23 +78,48 @@ fn invalid_precision() { } #[test] -fn format_nothing() { +fn format_empty() { same( "{}", &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), - position_span: InnerSpan { start: 2, end: 2 }, + position_span: 2..2, format: fmtdflt(), }))], ); } #[test] +fn format_tab_empty() { + let fmt_pre = r###""\t{}""###; + let fmt = "\t{}"; + let parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format); + assert_eq!( + parser.collect::>>(), + &[ + Lit("\t"), + NextArgument(Box::new(Argument { + position: ArgumentImplicitlyIs(0), + position_span: 4..4, + format: fmtdflt(), + })) + ], + ); +} +#[test] +fn format_open_brace_tab() { + let fmt_pre = r###""{\t""###; + let fmt = "{\t"; + let mut parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format); + let _ = parser.by_ref().collect::>>(); + assert_eq!(parser.errors[0].span, 4..4); +} +#[test] fn format_position() { same( "{3}", &[NextArgument(Box::new(Argument { position: ArgumentIs(3), - position_span: InnerSpan { start: 2, end: 3 }, + position_span: 2..3, format: fmtdflt(), }))], ); @@ -106,7 +130,7 @@ fn format_position_nothing_else() { "{3:}", &[NextArgument(Box::new(Argument { position: ArgumentIs(3), - position_span: InnerSpan { start: 2, end: 3 }, + position_span: 2..3, format: fmtdflt(), }))], ); @@ -117,18 +141,54 @@ fn format_named() { "{name}", &[NextArgument(Box::new(Argument { position: ArgumentNamed("name"), - position_span: InnerSpan { start: 2, end: 6 }, + position_span: 2..6, format: fmtdflt(), }))], ) } #[test] +fn format_named_space_nothing() { + same( + "{name} {}", + &[ + NextArgument(Box::new(Argument { + position: ArgumentNamed("name"), + position_span: 2..6, + format: fmtdflt(), + })), + Lit(" "), + NextArgument(Box::new(Argument { + position: ArgumentImplicitlyIs(0), + position_span: 9..9, + format: fmtdflt(), + })), + ], + ) +} +#[test] +fn format_raw() { + let snippet = r###"r#"assertion `left {op} right` failed"#"###.into(); + let source = r#"assertion `left {op} right` failed"#; + + let parser = Parser::new(source, Some(1), Some(snippet), true, ParseMode::Format); + let expected = &[ + Lit("assertion `left "), + NextArgument(Box::new(Argument { + position: ArgumentNamed("op"), + position_span: 20..22, + format: fmtdflt(), + })), + Lit(" right` failed"), + ]; + assert_eq!(parser.collect::>>(), expected); +} +#[test] fn format_type() { same( "{3:x}", &[NextArgument(Box::new(Argument { position: ArgumentIs(3), - position_span: InnerSpan { start: 2, end: 3 }, + position_span: 2..3, format: FormatSpec { fill: None, fill_span: None, @@ -153,7 +213,7 @@ fn format_align_fill() { "{3:>}", &[NextArgument(Box::new(Argument { position: ArgumentIs(3), - position_span: InnerSpan { start: 2, end: 3 }, + position_span: 2..3, format: FormatSpec { fill: None, fill_span: None, @@ -175,10 +235,10 @@ fn format_align_fill() { "{3:0<}", &[NextArgument(Box::new(Argument { position: ArgumentIs(3), - position_span: InnerSpan { start: 2, end: 3 }, + position_span: 2..3, format: FormatSpec { fill: Some('0'), - fill_span: Some(InnerSpan::new(4, 5)), + fill_span: Some(4..5), align: AlignLeft, sign: None, alternate: false, @@ -197,10 +257,10 @@ fn format_align_fill() { "{3:*>>(), + &[Lit("\n .intel_syntax noprefix\n nop")] + ); + assert_eq!(parser.line_spans, &[2..2, 11..33, 42..45]); +} +#[test] +fn asm_concat() { + let asm_pre = r###"concat!("invalid", "_", "instruction")"###; + let asm = "invalid_instruction"; + let mut parser = Parser::new(asm, None, Some(asm_pre.into()), false, ParseMode::InlineAsm); + assert!(!parser.is_source_literal); + assert_eq!(parser.by_ref().collect::>>(), &[Lit(asm)]); + assert_eq!(parser.line_spans, &[]); +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs index f835406122b8..d8b90844b7d2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs @@ -1,11 +1,12 @@ use std::fmt; +use std::ops::Range; use errors::*; use rustc_middle::ty::TyCtxt; use rustc_middle::ty::print::TraitRefPrintSugared; use rustc_parse_format::{ - Alignment, Argument, Count, FormatSpec, InnerSpan, ParseError, ParseMode, Parser, - Piece as RpfPiece, Position, + Alignment, Argument, Count, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece, + Position, }; use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::def_id::DefId; @@ -173,7 +174,7 @@ impl FormatString { pieces.push(Piece::Lit(lit.into())); } RpfPiece::NextArgument(arg) => { - warn_on_format_spec(arg.format, &mut warnings, span); + warn_on_format_spec(arg.format.clone(), &mut warnings, span); let arg = parse_arg(&arg, ctx, &mut warnings, span); pieces.push(Piece::Arg(arg)); } @@ -233,7 +234,7 @@ fn parse_arg<'tcx>( | Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx; let trait_name = tcx.item_ident(*trait_def_id); let generics = tcx.generics_of(trait_def_id); - let span = slice_span(input_span, arg.position_span); + let span = slice_span(input_span, arg.position_span.clone()); match arg.position { // Something like "hello {name}" @@ -335,14 +336,12 @@ fn warn_on_format_spec(spec: FormatSpec<'_>, warnings: &mut Vec, } } -/// Helper function because `Span` and `rustc_parse_format::InnerSpan` don't know about each other -fn slice_span(input: Span, inner: InnerSpan) -> Span { - let InnerSpan { start, end } = inner; +fn slice_span(input: Span, range: Range) -> Span { let span = input.data(); Span::new( - span.lo + BytePos::from_usize(start), - span.lo + BytePos::from_usize(end), + span.lo + BytePos::from_usize(range.start), + span.lo + BytePos::from_usize(range.end), span.ctxt, span.parent, ) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs index 9ef03065651a..d36e5205c739 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs @@ -224,7 +224,7 @@ impl ExprCollector<'_> { curarg = parser.curarg; - let to_span = |inner_span: rustc_parse_format::InnerSpan| { + let to_span = |inner_span: std::ops::Range| { is_direct_literal.then(|| { TextRange::new( inner_span.start.try_into().unwrap(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index 2fd21bb0ed3a..f27a4062a63b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -214,7 +214,7 @@ pub(crate) fn parse( }; } - let to_span = |inner_span: parse::InnerSpan| { + let to_span = |inner_span: std::ops::Range| { is_source_literal.then(|| { TextRange::new(inner_span.start.try_into().unwrap(), inner_span.end.try_into().unwrap()) }) @@ -297,7 +297,7 @@ pub(crate) fn parse( unfinished_literal.clear(); } - let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s)); + let span = parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone())); placeholder_index += 1; let position_span = to_span(position_span); From 4d5a1acebfe031ca2af75786295a2cd2a0633943 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 12 Apr 2025 17:52:55 +1000 Subject: [PATCH 190/262] coverage: Only merge adjacent coverage spans This also removes some manipulation of the function signature span that only made sense in the context of merging non-adjacent spans. --- .../src/coverage/mappings.rs | 2 +- .../rustc_mir_transform/src/coverage/mod.rs | 30 +- .../rustc_mir_transform/src/coverage/spans.rs | 26 +- tests/coverage/abort.cov-map | 28 +- tests/coverage/assert-ne.cov-map | 19 +- tests/coverage/assert.cov-map | 24 +- tests/coverage/assert_not.cov-map | 17 +- tests/coverage/async.cov-map | 181 +++++---- tests/coverage/async.coverage | 14 +- tests/coverage/async2.cov-map | 79 ++-- tests/coverage/async2.coverage | 4 +- tests/coverage/async_block.cov-map | 19 +- tests/coverage/async_closure.cov-map | 34 +- tests/coverage/async_closure.coverage | 3 +- tests/coverage/attr/impl.cov-map | 21 +- tests/coverage/attr/module.cov-map | 21 +- tests/coverage/attr/nested.cov-map | 20 +- tests/coverage/attr/off-on-sandwich.cov-map | 30 +- .../coverage/attr/trait-impl-inherit.cov-map | 9 +- tests/coverage/await_ready.cov-map | 13 +- tests/coverage/await_ready.coverage | 2 +- tests/coverage/bad_counter_ids.cov-map | 100 +++-- tests/coverage/bench.cov-map | 7 +- tests/coverage/branch/generics.cov-map | 27 +- tests/coverage/branch/guard.cov-map | 15 +- tests/coverage/branch/guard.coverage | 2 +- tests/coverage/branch/if-let.cov-map | 49 ++- tests/coverage/branch/if.cov-map | 39 +- tests/coverage/branch/lazy-boolean.cov-map | 58 ++- tests/coverage/branch/let-else.cov-map | 17 +- tests/coverage/branch/match-arms.cov-map | 85 ++-- tests/coverage/branch/match-trivial.cov-map | 29 +- tests/coverage/branch/match-trivial.coverage | 4 +- tests/coverage/branch/no-mir-spans.cov-map | 16 +- tests/coverage/branch/while.cov-map | 48 ++- tests/coverage/closure.cov-map | 377 +++++++++++------- tests/coverage/closure.coverage | 74 ++-- tests/coverage/closure_bug.cov-map | 45 ++- tests/coverage/closure_bug.coverage | 2 +- tests/coverage/closure_macro.cov-map | 46 ++- tests/coverage/closure_macro.coverage | 2 +- tests/coverage/closure_macro_async.cov-map | 50 ++- tests/coverage/closure_macro_async.coverage | 2 +- tests/coverage/closure_unit_return.cov-map | 39 +- tests/coverage/closure_unit_return.coverage | 4 +- tests/coverage/condition/conditions.cov-map | 64 +-- tests/coverage/conditions.cov-map | 199 +++++---- tests/coverage/continue.cov-map | 95 +++-- tests/coverage/continue.coverage | 4 +- tests/coverage/coroutine.cov-map | 37 +- tests/coverage/coverage_attr_closure.cov-map | 36 +- tests/coverage/dead_code.cov-map | 39 +- tests/coverage/dead_code.coverage | 24 +- tests/coverage/drop_trait.cov-map | 40 +- tests/coverage/drop_trait.coverage | 8 +- tests/coverage/fn_sig_into_try.cov-map | 48 ++- tests/coverage/fn_sig_into_try.coverage | 16 +- tests/coverage/generic-unused-impl.cov-map | 17 +- tests/coverage/generics.cov-map | 107 +++-- tests/coverage/generics.coverage | 8 +- tests/coverage/holes.cov-map | 76 ++-- tests/coverage/holes.coverage | 18 +- tests/coverage/if.cov-map | 13 +- tests/coverage/if.coverage | 20 +- tests/coverage/if_else.cov-map | 13 +- tests/coverage/if_else.coverage | 10 +- tests/coverage/if_not.cov-map | 9 +- tests/coverage/if_not.coverage | 2 +- tests/coverage/ignore_run.cov-map | 7 +- tests/coverage/inline-dead.cov-map | 39 +- tests/coverage/inline-dead.coverage | 2 +- tests/coverage/inline.cov-map | 111 ++++-- tests/coverage/inline.coverage | 2 +- tests/coverage/inner_items.cov-map | 52 ++- tests/coverage/inner_items.coverage | 10 +- tests/coverage/issue-83601.cov-map | 27 +- tests/coverage/issue-84561.cov-map | 120 ++++-- tests/coverage/issue-84561.coverage | 14 +- tests/coverage/issue-85461.cov-map | 9 +- tests/coverage/issue-93054.cov-map | 19 +- tests/coverage/lazy_boolean.cov-map | 18 +- tests/coverage/lazy_boolean.coverage | 8 +- tests/coverage/let_else_loop.cov-map | 27 +- tests/coverage/long_and_wide.cov-map | 32 +- tests/coverage/long_and_wide.coverage | 262 ++++++------ tests/coverage/loop-break.cov-map | 4 +- tests/coverage/loop_break_value.cov-map | 9 +- tests/coverage/loop_break_value.coverage | 4 +- tests/coverage/loops_branches.cov-map | 49 ++- tests/coverage/macro_in_closure.cov-map | 13 +- tests/coverage/macro_name_span.cov-map | 15 +- tests/coverage/match_or_pattern.cov-map | 17 +- tests/coverage/match_or_pattern.coverage | 8 +- tests/coverage/mcdc/condition-limit.cov-map | 17 +- tests/coverage/mcdc/if.cov-map | 95 +++-- tests/coverage/mcdc/if.coverage | 8 +- .../coverage/mcdc/inlined_expressions.cov-map | 9 +- tests/coverage/mcdc/nested_if.cov-map | 36 +- tests/coverage/mcdc/nested_if.coverage | 6 +- tests/coverage/mcdc/non_control_flow.cov-map | 63 +-- tests/coverage/nested_loops.cov-map | 68 ++-- tests/coverage/no-core.cov-map | 7 +- tests/coverage/no_cov_crate.cov-map | 79 ++-- tests/coverage/no_cov_crate.coverage | 4 +- tests/coverage/no_spans.cov-map | 14 +- tests/coverage/no_spans.coverage | 21 +- tests/coverage/no_spans.rs | 13 +- tests/coverage/no_spans_if_not.cov-map | 17 +- tests/coverage/overflow.cov-map | 41 +- tests/coverage/panic_unwind.cov-map | 28 +- tests/coverage/partial_eq.cov-map | 23 +- tests/coverage/partial_eq.coverage | 8 +- tests/coverage/simple_loop.cov-map | 22 +- tests/coverage/simple_loop.coverage | 12 +- tests/coverage/simple_match.cov-map | 17 +- tests/coverage/simple_match.coverage | 8 +- tests/coverage/sort_groups.cov-map | 75 ++-- tests/coverage/test_harness.cov-map | 14 +- tests/coverage/tight_inf_loop.cov-map | 12 +- tests/coverage/trivial.cov-map | 7 +- tests/coverage/try_error_result.cov-map | 254 +++++++----- tests/coverage/try_error_result.coverage | 12 +- tests/coverage/unicode.cov-map | 24 +- tests/coverage/unicode.coverage | 2 +- tests/coverage/unreachable.cov-map | 18 +- tests/coverage/unused.cov-map | 67 ++-- tests/coverage/unused_mod.cov-map | 18 +- tests/coverage/uses_crate.cov-map | 52 ++- tests/coverage/uses_crate.coverage | 10 +- tests/coverage/uses_inline_crate.cov-map | 69 +++- tests/coverage/uses_inline_crate.coverage | 20 +- tests/coverage/while.cov-map | 10 +- tests/coverage/while_early_ret.cov-map | 21 +- tests/coverage/yield.cov-map | 55 ++- ...ch_match_arms.main.InstrumentCoverage.diff | 19 +- ...ument_coverage.bar.InstrumentCoverage.diff | 4 +- ...ment_coverage.main.InstrumentCoverage.diff | 2 +- ...rage_cleanup.main.CleanupPostBorrowck.diff | 3 +- ...erage_cleanup.main.InstrumentCoverage.diff | 3 +- 139 files changed, 2982 insertions(+), 1919 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 73bd2d0705e1..b4b4d0416fb9 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -91,7 +91,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>( // When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need // to give the same treatment to _all_ functions, because `llvm-cov` // seems to ignore functions that don't have any ordinary code spans. - if let Some(span) = hir_info.fn_sig_span_extended { + if let Some(span) = hir_info.fn_sig_span { code_mappings.push(CodeMapping { span, bcb: START_BCB }); } } else { diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index f2e8f9e1bcd6..702c62eddc7f 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -268,9 +268,9 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb struct ExtractedHirInfo { function_source_hash: u64, is_async_fn: bool, - /// The span of the function's signature, extended to the start of `body_span`. + /// The span of the function's signature, if available. /// Must have the same context and filename as the body span. - fn_sig_span_extended: Option, + fn_sig_span: Option, body_span: Span, /// "Holes" are regions within the function body (or its expansions) that /// should not be included in coverage spans for this function @@ -308,30 +308,20 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir // The actual signature span is only used if it has the same context and // filename as the body, and precedes the body. - let fn_sig_span_extended = maybe_fn_sig - .map(|fn_sig| fn_sig.span) - .filter(|&fn_sig_span| { - let source_map = tcx.sess.source_map(); - let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo()); + let fn_sig_span = maybe_fn_sig.map(|fn_sig| fn_sig.span).filter(|&fn_sig_span| { + let source_map = tcx.sess.source_map(); + let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo()); - fn_sig_span.eq_ctxt(body_span) - && fn_sig_span.hi() <= body_span.lo() - && file_idx(fn_sig_span) == file_idx(body_span) - }) - // If so, extend it to the start of the body span. - .map(|fn_sig_span| fn_sig_span.with_hi(body_span.lo())); + fn_sig_span.eq_ctxt(body_span) + && fn_sig_span.hi() <= body_span.lo() + && file_idx(fn_sig_span) == file_idx(body_span) + }); let function_source_hash = hash_mir_source(tcx, hir_body); let hole_spans = extract_hole_spans_from_hir(tcx, hir_body); - ExtractedHirInfo { - function_source_hash, - is_async_fn, - fn_sig_span_extended, - body_span, - hole_spans, - } + ExtractedHirInfo { function_source_hash, is_async_fn, fn_sig_span, body_span, hole_spans } } fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 { diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index f57a158e3e4a..e6e7e2920ec0 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -42,12 +42,12 @@ pub(super) fn extract_refined_covspans<'tcx>( return; } - // Also add the adjusted function signature span, if available. + // Also add the function signature span, if available. // Otherwise, add a fake span at the start of the body, to avoid an ugly // gap between the start of the body and the first real span. // FIXME: Find a more principled way to solve this problem. covspans.push(SpanFromMir::for_fn_sig( - hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo()), + hir_info.fn_sig_span.unwrap_or_else(|| body_span.shrink_to_lo()), )); // First, perform the passes that need macro information. @@ -227,19 +227,21 @@ struct Covspan { } impl Covspan { - /// If `self` and `other` can be merged (i.e. they have the same BCB), - /// mutates `self.span` to also include `other.span` and returns true. + /// If `self` and `other` can be merged, mutates `self.span` to also + /// include `other.span` and returns true. /// - /// Note that compatible covspans can be merged even if their underlying - /// spans are not overlapping/adjacent; any space between them will also be - /// part of the merged covspan. + /// Two covspans can be merged if they have the same BCB, and they are + /// overlapping or adjacent. fn merge_if_eligible(&mut self, other: &Self) -> bool { - if self.bcb != other.bcb { - return false; - } + let eligible_for_merge = + |a: &Self, b: &Self| (a.bcb == b.bcb) && a.span.overlaps_or_adjacent(b.span); - self.span = self.span.to(other.span); - true + if eligible_for_merge(self, other) { + self.span = self.span.to(other.span); + true + } else { + false + } } } diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map index 4021537392b9..4d8ea874bd79 100644 --- a/tests/coverage/abort.cov-map +++ b/tests/coverage/abort.cov-map @@ -1,5 +1,5 @@ Function name: abort::main -Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] +Raw bytes (98): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 10, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/abort.rs Number of expressions: 7 @@ -10,9 +10,11 @@ Number of expressions: 7 - expression 4 operands: lhs = Counter(0), rhs = Counter(3) - expression 5 operands: lhs = Counter(1), rhs = Expression(6, Add) - expression 6 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24) +Number of file 0 mappings: 16 +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24) - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 25) = (c1 - c0) - Code(Counter(2)) at (prev + 0, 26) to (start + 2, 10) @@ -30,19 +32,25 @@ Number of file 0 mappings: 13 = (c1 - (c0 + c4)) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23) = (c1 - c0) -- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c4 Function name: abort::might_abort -Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02] +Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 03, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 1f, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/abort.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20) -- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15) -- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 31) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15) +- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2) = (c0 - c1) Highest counter ID seen: c1 diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map index 4bee7d7b97c7..fde0d5184d67 100644 --- a/tests/coverage/assert-ne.cov-map +++ b/tests/coverage/assert-ne.cov-map @@ -1,16 +1,23 @@ Function name: assert_ne::main -Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02] +Raw bytes (55): 0x[01, 01, 03, 01, 05, 01, 09, 01, 09, 09, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 12, 01, 00, 13, 00, 19, 01, 01, 0c, 00, 15, 05, 01, 0d, 00, 13, 02, 02, 0d, 00, 13, 0a, 03, 05, 00, 07, 0a, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/assert-ne.rs -Number of expressions: 2 +Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 21) -- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 25) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 21) +- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19) = (c0 - c1) -- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2) +- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 0, 7) + = (c0 - c2) +- Code(Expression(2, Sub)) at (prev + 1, 1) to (start + 0, 2) = (c0 - c2) Highest counter ID seen: c1 diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map index e7ee91979711..07a0d4c8c27e 100644 --- a/tests/coverage/assert.cov-map +++ b/tests/coverage/assert.cov-map @@ -1,5 +1,5 @@ Function name: assert::main -Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] +Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 09, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/assert.rs Number of expressions: 6 @@ -9,9 +9,11 @@ Number of expressions: 6 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) - expression 5 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24) - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26) = (c1 - c0) - Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10) @@ -22,18 +24,22 @@ Number of file 0 mappings: 9 = (c1 - ((c0 + c2) + c3)) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23) = (c1 - c0) -- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: assert::might_fail_assert -Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 04, 01, 00, 28, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 01, 01, 05, 00, 0f, 02, 00, 25, 00, 3d, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/assert.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 15) -- Code(Expression(0, Sub)) at (prev + 2, 37) to (start + 0, 61) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 40) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Expression(0, Sub)) at (prev + 0, 37) to (start + 0, 61) = (c0 - c1) - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map index d3ef867a8a82..e0ec3815244e 100644 --- a/tests/coverage/assert_not.cov-map +++ b/tests/coverage/assert_not.cov-map @@ -1,13 +1,18 @@ Function name: assert_not::main -Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02] +Raw bytes (54): 0x[01, 01, 00, 0a, 01, 06, 01, 00, 0a, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 11, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 15, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/assert_not.rs Number of expressions: 0 -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17) -- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 21) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index 8d8dd2430571..c528ad525b5f 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -1,115 +1,125 @@ Function name: async::c -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 18] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 24) Highest counter ID seen: c0 Function name: async::c::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 19, 00, 1a, 01, 01, 08, 00, 0e, 05, 01, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 11, 25) to (start + 1, 14) -- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 11, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: async::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 13] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 19) Highest counter ID seen: c0 Function name: async::d::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 13, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 13] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 1) to (start + 0, 20) +- Code(Zero) at (prev + 21, 1) to (start + 0, 19) Highest counter ID seen: (none) Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 14, 00, 19] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 15, 14, 00, 15, 00, 00, 16, 00, 17, 00, 00, 18, 00, 19] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 20) to (start + 0, 25) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 21, 20) to (start + 0, 21) +- Code(Zero) at (prev + 0, 22) to (start + 0, 23) +- Code(Zero) at (prev + 0, 24) to (start + 0, 25) Highest counter ID seen: (none) Function name: async::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 13] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 19) Highest counter ID seen: c0 Function name: async::f::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 14, 00, 19] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 17, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 25) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1d] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 1) to (start + 0, 30) +- Code(Zero) at (prev + 25, 1) to (start + 0, 29) Highest counter ID seen: (none) Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 1e, 00, 2d] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 1e, 00, 1f, 00, 00, 20, 00, 2b, 00, 00, 2c, 00, 2d] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 30) to (start + 0, 45) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 25, 30) to (start + 0, 31) +- Code(Zero) at (prev + 0, 32) to (start + 0, 43) +- Code(Zero) at (prev + 0, 44) to (start + 0, 45) Highest counter ID seen: (none) Function name: async::g -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 16] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 22) Highest counter ID seen: c0 Function name: async::g::{closure#0} (unused) -Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1b, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (64): 0x[01, 01, 00, 0c, 00, 1b, 17, 00, 18, 00, 01, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 11 -- Code(Zero) at (prev + 27, 23) to (start + 1, 12) -- Code(Zero) at (prev + 2, 9) to (start + 0, 10) +Number of file 0 mappings: 12 +- Code(Zero) at (prev + 27, 23) to (start + 0, 24) +- Code(Zero) at (prev + 1, 11) to (start + 0, 12) +- Code(Zero) at (prev + 1, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 23) - Code(Zero) at (prev + 0, 27) to (start + 0, 28) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) @@ -122,22 +132,23 @@ Number of file 0 mappings: 11 Highest counter ID seen: (none) Function name: async::h -Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 16] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 15] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 21) Highest counter ID seen: c0 Function name: async::h::{closure#0} (unused) -Raw bytes (39): 0x[01, 01, 00, 07, 00, 23, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 00, 23, 16, 00, 17, 00, 03, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 7 -- Code(Zero) at (prev + 35, 22) to (start + 3, 12) -- Code(Zero) at (prev + 4, 9) to (start + 0, 10) +Number of file 0 mappings: 8 +- Code(Zero) at (prev + 35, 22) to (start + 0, 23) +- Code(Zero) at (prev + 3, 11) to (start + 0, 12) +- Code(Zero) at (prev + 1, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 25) - Code(Zero) at (prev + 0, 26) to (start + 0, 27) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) @@ -146,25 +157,27 @@ Number of file 0 mappings: 7 Highest counter ID seen: (none) Function name: async::i -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 13] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 12] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 18) Highest counter ID seen: c0 Function name: async::i::{closure#0} -Raw bytes (65): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] +Raw bytes (75): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0d, 01, 2c, 13, 00, 14, 01, 04, 0b, 00, 0c, 09, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(4), rhs = Counter(5) - expression 2 operands: lhs = Counter(3), rhs = Counter(4) -Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 44, 19) to (start + 4, 12) -- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 44, 19) to (start + 0, 20) +- Code(Counter(0)) at (prev + 4, 11) to (start + 0, 12) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24) - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33) - Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48) @@ -180,17 +193,18 @@ Number of file 0 mappings: 11 Highest counter ID seen: c5 Function name: async::j -Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0b, 01, 37, 01, 00, 0c, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 13) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 12) - Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12) - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10) @@ -203,60 +217,67 @@ Number of file 0 mappings: 10 Highest counter ID seen: c2 Function name: async::j::c -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 39, 05, 00, 16, 01, 01, 0c, 00, 12, 05, 01, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 57, 5) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 57, 5) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 14) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 14) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: async::j::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 40, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) Highest counter ID seen: c0 Function name: async::j::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 41, 05, 00, 17] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 41, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 23) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) Highest counter ID seen: c0 Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 00, 49, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 00, 49, 01, 00, 0c, 00, 01, 0b, 00, 0c, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 5 -- Code(Zero) at (prev + 73, 1) to (start + 1, 12) -- Code(Zero) at (prev + 2, 14) to (start + 0, 16) +Number of file 0 mappings: 6 +- Code(Zero) at (prev + 73, 1) to (start + 0, 12) +- Code(Zero) at (prev + 1, 11) to (start + 0, 12) +- Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: async::l -Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 51, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 02, 01, 07, 05, 09, 06, 01, 51, 01, 00, 0c, 01, 01, 0b, 00, 0c, 02, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 81, 1) to (start + 1, 12) -- Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 81, 1) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 12) +- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 16) = (c0 - (c1 + c2)) - Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) @@ -264,29 +285,43 @@ Number of file 0 mappings: 5 Highest counter ID seen: c2 Function name: async::m -Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 18] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 24) Highest counter ID seen: c0 Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 59, 19, 00, 22] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 59, 19, 00, 1a, 00, 00, 1b, 00, 20, 00, 00, 21, 00, 22] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 89, 25) to (start + 0, 34) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 89, 25) to (start + 0, 26) +- Code(Zero) at (prev + 0, 27) to (start + 0, 32) +- Code(Zero) at (prev + 0, 33) to (start + 0, 34) Highest counter ID seen: (none) Function name: async::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 08, 02] +Raw bytes (69): 0x[01, 01, 00, 0d, 01, 5b, 01, 00, 0a, 01, 01, 0d, 00, 12, 01, 01, 0d, 00, 11, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1e, 01, 00, 1f, 00, 20, 01, 01, 05, 00, 06, 01, 01, 05, 00, 06, 01, 01, 0d, 00, 11, 01, 01, 05, 00, 17, 01, 00, 18, 00, 1e, 01, 00, 1f, 00, 25, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 91, 1) to (start + 8, 2) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 30) +- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 30) +- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage index aee76b05fb74..9fca1b6997d0 100644 --- a/tests/coverage/async.coverage +++ b/tests/coverage/async.coverage @@ -25,6 +25,7 @@ LL| 0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()` LL| | LL| 1|pub async fn g(x: u8) { + ^0 LL| 0| match x { LL| 0| y if e().await == y => (), LL| 0| y if f().await == y => (), @@ -33,8 +34,9 @@ LL| 0|} LL| | LL| 1|async fn h(x: usize) { // The function signature is counted when called, but the body is not - LL| 0| // executed (not awaited) so the open brace has a `0` count (at least when - LL| 0| // displayed with `llvm-cov show` in color-mode). + ^0 + LL| | // executed (not awaited) so the open brace has a `0` count (at least when + LL| | // displayed with `llvm-cov show` in color-mode). LL| 0| match x { LL| 0| y if foo().await[y] => (), LL| 0| _ => (), @@ -42,9 +44,9 @@ LL| 0|} LL| | LL| 1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions: - LL| 1| // (a) the function signature, counted when the function is called; and - LL| 1| // (b) the open brace for the function body, counted once when the body is - LL| 1| // executed asynchronously. + LL| | // (a) the function signature, counted when the function is called; and + LL| | // (b) the open brace for the function body, counted once when the body is + LL| | // executed asynchronously. LL| 1| match x { LL| 1| y if c(x).await == y + 1 => { d().await; } ^0 ^0 @@ -91,7 +93,7 @@ LL| 1|} LL| | LL| 1|async fn m(x: u8) -> u8 { x - 1 } - ^0 + ^0^0 ^0 LL| | LL| 1|fn main() { LL| 1| let _ = g(10); diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map index 43ec9f397bd9..cc6295170980 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -1,59 +1,80 @@ Function name: async2::async_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 16] Number of files: 1 - file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 22) Highest counter ID seen: c0 Function name: async2::async_func::{closure#0} -Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (49): 0x[01, 01, 00, 09, 01, 0f, 17, 00, 18, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async2.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9) -- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 15, 23) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: async2::async_func_just_println -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 23] Number of files: 1 - file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 35) Highest counter ID seen: c0 Function name: async2::async_func_just_println::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 24, 02, 02] -Number of files: 1 -- file 0 => $DIR/async2.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 36) to (start + 2, 2) -Highest counter ID seen: c0 - -Function name: async2::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 07, 02] -Number of files: 1 -- file 0 => $DIR/async2.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 2) -Highest counter ID seen: c0 - -Function name: async2::non_async_func -Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 17, 24, 00, 25, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 33, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async2.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9) -- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6) +- Code(Counter(0)) at (prev + 23, 36) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 51) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 + +Function name: async2::main +Raw bytes (49): 0x[01, 01, 00, 09, 01, 1b, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 23, 01, 02, 05, 00, 13, 01, 02, 05, 00, 17, 01, 00, 18, 00, 22, 01, 01, 05, 00, 17, 01, 00, 18, 00, 2f, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/async2.rs +Number of expressions: 0 +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 35) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 47) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 + +Function name: async2::non_async_func +Raw bytes (49): 0x[01, 01, 00, 09, 01, 07, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/async2.rs +Number of expressions: 0 +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 42) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage index fa56072924bb..e9ed8253093d 100644 --- a/tests/coverage/async2.coverage +++ b/tests/coverage/async2.coverage @@ -28,9 +28,9 @@ LL| | LL| 1|fn main() { LL| 1| println!("codecovsample::main"); - LL| 1| + LL| | LL| 1| non_async_func(); - LL| 1| + LL| | LL| 1| executor::block_on(async_func()); LL| 1| executor::block_on(async_func_just_println()); LL| 1|} diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map index 9e76bb981ffe..07d4c0eb3cd6 100644 --- a/tests/coverage/async_block.cov-map +++ b/tests/coverage/async_block.cov-map @@ -1,30 +1,33 @@ Function name: async_block::main -Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 22, 01, 02, 01, 00, 02] +Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async_block.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 11) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) = (c1 - c0) -- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 34) +- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 27) + = (c1 - c0) +- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 34) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: async_block::main::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 09, 1c, 00, 1d, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/async_block.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 9, 28) to (start + 1, 23) -- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 9, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23) +- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14) - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14) = (c0 - c1) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index 10b6db0fc713..9f8dc8d6cbba 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -1,32 +1,39 @@ Function name: async_closure::call_once:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2a] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 42) Highest counter ID seen: c0 Function name: async_closure::call_once::::{closure#0} -Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 06, 2b, 01, 0e, 02, 02, 01, 00, 02] +Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 2b, 00, 2c, 01, 01, 05, 00, 0e, 02, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14) -- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 6, 43) to (start + 0, 44) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2) = (c1 - c2) Highest counter ID seen: c0 Function name: async_closure::main -Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 01, 0a, 01, 00, 0e, 01, 01, 09, 00, 16, 01, 01, 05, 00, 17, 01, 00, 18, 00, 27, 01, 01, 05, 00, 17, 01, 00, 18, 00, 21, 01, 00, 22, 00, 2f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22) -- Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 39) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 33) +- Code(Counter(0)) at (prev + 0, 34) to (start + 0, 47) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} @@ -50,11 +57,12 @@ Number of file 0 mappings: 2 Highest counter ID seen: c0 Function name: async_closure::main::{closure#0}::{closure#0}:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) +- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36) Highest counter ID seen: c0 diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage index 5aed131de2e5..14f043415eac 100644 --- a/tests/coverage/async_closure.coverage +++ b/tests/coverage/async_closure.coverage @@ -8,7 +8,8 @@ LL| 1|} LL| | LL| 1|pub fn main() { - LL| 2| let async_closure = async || {}; + LL| 3| let async_closure = async || {}; + ^1 ------------------ | async_closure::main::{closure#0}: | LL| 1| let async_closure = async || {}; diff --git a/tests/coverage/attr/impl.cov-map b/tests/coverage/attr/impl.cov-map index ad24dfb63229..0562c291e6c1 100644 --- a/tests/coverage/attr/impl.cov-map +++ b/tests/coverage/attr/impl.cov-map @@ -1,27 +1,30 @@ Function name: ::off_on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 05, 00, 13] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 0f, 05, 00, 10, 00, 00, 12, 00, 13] Number of files: 1 - file 0 => $DIR/impl.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 5) to (start + 0, 19) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 15, 5) to (start + 0, 16) +- Code(Zero) at (prev + 0, 18) to (start + 0, 19) Highest counter ID seen: (none) Function name: ::on_inherit (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 17] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 17, 05, 00, 14, 00, 00, 16, 00, 17] Number of files: 1 - file 0 => $DIR/impl.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 23, 5) to (start + 0, 23) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 23, 5) to (start + 0, 20) +- Code(Zero) at (prev + 0, 22) to (start + 0, 23) Highest counter ID seen: (none) Function name: ::on_on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 05, 00, 12] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 1a, 05, 00, 0f, 00, 00, 11, 00, 12] Number of files: 1 - file 0 => $DIR/impl.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 26, 5) to (start + 0, 18) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 26, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 17) to (start + 0, 18) Highest counter ID seen: (none) diff --git a/tests/coverage/attr/module.cov-map b/tests/coverage/attr/module.cov-map index eba24da0dd1e..88f4915bfe8f 100644 --- a/tests/coverage/attr/module.cov-map +++ b/tests/coverage/attr/module.cov-map @@ -1,27 +1,30 @@ Function name: module::off::on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0d, 05, 00, 0f] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 0d, 05, 00, 0c, 00, 00, 0e, 00, 0f] Number of files: 1 - file 0 => $DIR/module.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 13, 5) to (start + 0, 15) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 13, 5) to (start + 0, 12) +- Code(Zero) at (prev + 0, 14) to (start + 0, 15) Highest counter ID seen: (none) Function name: module::on::inherit (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 05, 00, 14] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 05, 00, 11, 00, 00, 13, 00, 14] Number of files: 1 - file 0 => $DIR/module.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 5) to (start + 0, 20) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 21, 5) to (start + 0, 17) +- Code(Zero) at (prev + 0, 19) to (start + 0, 20) Highest counter ID seen: (none) Function name: module::on::on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 05, 00, 0f] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 18, 05, 00, 0c, 00, 00, 0e, 00, 0f] Number of files: 1 - file 0 => $DIR/module.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 24, 5) to (start + 0, 15) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 24, 5) to (start + 0, 12) +- Code(Zero) at (prev + 0, 14) to (start + 0, 15) Highest counter ID seen: (none) diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map index a831340bce5e..8ca218f7267f 100644 --- a/tests/coverage/attr/nested.cov-map +++ b/tests/coverage/attr/nested.cov-map @@ -1,20 +1,24 @@ Function name: nested::closure_expr -Raw bytes (14): 0x[01, 01, 00, 02, 01, 40, 01, 01, 0f, 01, 0b, 05, 01, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 40, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 0a, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 64, 1) to (start + 1, 15) -- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 64, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: nested::closure_tail -Raw bytes (14): 0x[01, 01, 00, 02, 01, 4f, 01, 01, 0f, 01, 11, 05, 01, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 4f, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 10, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 79, 1) to (start + 1, 15) -- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map index d26f06bb81f5..c0c6eab57108 100644 --- a/tests/coverage/attr/off-on-sandwich.cov-map +++ b/tests/coverage/attr/off-on-sandwich.cov-map @@ -1,30 +1,36 @@ Function name: off_on_sandwich::dense_a::dense_b -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 10, 01, 07, 05, 00, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 10, 05, 00, 11, 01, 01, 09, 00, 10, 01, 01, 09, 00, 10, 01, 05, 05, 00, 06] Number of files: 1 - file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 5) to (start + 2, 16) -- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c -Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 15, 01, 0b, 09, 00, 0a] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 22, 09, 00, 16, 01, 01, 0d, 00, 15, 01, 01, 0d, 00, 15, 01, 09, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 34, 9) to (start + 2, 21) -- Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 34, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) +- Code(Counter(0)) at (prev + 9, 9) to (start + 0, 10) Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d -Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 19, 01, 07, 0d, 00, 0e] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 25, 0d, 00, 1a, 01, 01, 11, 00, 19, 01, 01, 11, 00, 19, 01, 05, 0d, 00, 0e] Number of files: 1 - file 0 => $DIR/off-on-sandwich.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 37, 13) to (start + 2, 25) -- Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 37, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25) +- Code(Counter(0)) at (prev + 5, 13) to (start + 0, 14) Highest counter ID seen: c0 diff --git a/tests/coverage/attr/trait-impl-inherit.cov-map b/tests/coverage/attr/trait-impl-inherit.cov-map index b3e875785926..bf10083dd290 100644 --- a/tests/coverage/attr/trait-impl-inherit.cov-map +++ b/tests/coverage/attr/trait-impl-inherit.cov-map @@ -1,9 +1,12 @@ Function name: ::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 10, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/trait-impl-inherit.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c0 diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map index 7bff6a4a7748..a7eb051ff093 100644 --- a/tests/coverage/await_ready.cov-map +++ b/tests/coverage/await_ready.cov-map @@ -1,21 +1,22 @@ Function name: await_ready::await_ready -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1d] Number of files: 1 - file 0 => $DIR/await_ready.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 30) +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 29) Highest counter ID seen: c0 Function name: await_ready::await_ready::{closure#0} -Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 0e, 1e, 03, 0f, 02, 04, 01, 00, 02] +Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 0e, 1e, 00, 1f, 01, 02, 05, 01, 0f, 02, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/await_ready.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 14, 30) to (start + 3, 15) -- Code(Expression(0, Sub)) at (prev + 4, 1) to (start + 0, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 14, 30) to (start + 0, 31) +- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 15) +- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2) = (c1 - c2) Highest counter ID seen: c0 diff --git a/tests/coverage/await_ready.coverage b/tests/coverage/await_ready.coverage index 1150d807e763..9a2d8f5a4fdf 100644 --- a/tests/coverage/await_ready.coverage +++ b/tests/coverage/await_ready.coverage @@ -12,7 +12,7 @@ LL| |#[coverage(on)] LL| |#[rustfmt::skip] LL| 1|async fn await_ready() -> u8 { - LL| 1| // await should be covered even if the function never yields + LL| | // await should be covered even if the function never yields LL| 1| ready() LL| 1| .await LL| 1|} diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map index 2ef299307261..8b1b177f906e 100644 --- a/tests/coverage/bad_counter_ids.cov-map +++ b/tests/coverage/bad_counter_ids.cov-map @@ -1,84 +1,108 @@ Function name: bad_counter_ids::eq_bad -Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 0f, 00, 03, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 24, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 15) -- Code(Zero) at (prev + 3, 1) to (start + 0, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::eq_bad_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 29, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15) -- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 0f, 01, 03, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 15) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 15, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15) -- Code(Zero) at (prev + 2, 32) to (start + 0, 43) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 32) to (start + 0, 43) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::ne_bad -Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 0f, 00, 03, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 2e, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 15) -- Code(Zero) at (prev + 3, 1) to (start + 0, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 46, 1) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::ne_bad_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15) -- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 51, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::ne_good -Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 0f, 01, 03, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 1a, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/bad_counter_ids.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 15) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c0 - -Function name: bad_counter_ids::ne_good_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/bad_counter_ids.rs -Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15) -- Code(Zero) at (prev + 2, 32) to (start + 0, 43) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 + +Function name: bad_counter_ids::ne_good_message +Raw bytes (34): 0x[01, 01, 00, 06, 01, 1f, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/bad_counter_ids.rs +Number of expressions: 0 +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 32) to (start + 0, 43) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map index 1707957fddc1..f2b21ddb70bb 100644 --- a/tests/coverage/bench.cov-map +++ b/tests/coverage/bench.cov-map @@ -1,9 +1,10 @@ Function name: bench::my_bench -Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 00, 27] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 01, 00, 24, 01, 00, 26, 00, 27] Number of files: 1 - file 0 => $DIR/bench.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 0, 38) to (start + 0, 39) Highest counter ID seen: c0 diff --git a/tests/coverage/branch/generics.cov-map b/tests/coverage/branch/generics.cov-map index 50e6eedb676f..cb03f2a79f76 100644 --- a/tests/coverage/branch/generics.cov-map +++ b/tests/coverage/branch/generics.cov-map @@ -1,12 +1,13 @@ Function name: generics::print_size::<()> -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) -- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) @@ -16,14 +17,15 @@ Number of file 0 mappings: 5 Highest counter ID seen: c1 Function name: generics::print_size:: -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) -- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) @@ -33,14 +35,15 @@ Number of file 0 mappings: 5 Highest counter ID seen: c1 Function name: generics::print_size:: -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/generics.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) -- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map index c1a275b34a3f..9c6a9bf40fd1 100644 --- a/tests/coverage/branch/guard.cov-map +++ b/tests/coverage/branch/guard.cov-map @@ -1,5 +1,5 @@ Function name: guard::branch_match_guard -Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 0e, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02] +Raw bytes (104): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 10, 01, 0c, 01, 00, 26, 01, 01, 05, 00, 0e, 02, 02, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 00, 1e, 0d, 00, 22, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 00, 1e, 11, 00, 22, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02] Number of files: 1 - file 0 => $DIR/guard.rs Number of expressions: 8 @@ -11,9 +11,10 @@ Number of expressions: 8 - expression 5 operands: lhs = Counter(0), rhs = Counter(1) - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4) - expression 7 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14) -- Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12) +Number of file 0 mappings: 16 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 2, 11) to (start + 0, 12) = (c1 - c3) - Code(Expression(1, Sub)) at (prev + 1, 20) to (start + 2, 10) = (c2 - c1) @@ -22,14 +23,16 @@ Number of file 0 mappings: 13 - Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 30) true = c3 false = (c1 - c3) -- Code(Counter(3)) at (prev + 0, 29) to (start + 2, 10) +- Code(Counter(3)) at (prev + 0, 29) to (start + 0, 30) +- Code(Counter(3)) at (prev + 0, 34) to (start + 2, 10) - Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15) - Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25) = (c1 - c3) - Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 30) true = c4 false = (c1 - (c3 + c4)) -- Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10) +- Code(Counter(4)) at (prev + 0, 29) to (start + 0, 30) +- Code(Counter(4)) at (prev + 0, 34) to (start + 2, 10) - Code(Expression(4, Sub)) at (prev + 3, 14) to (start + 2, 10) = ((c0 + c1) - ((c2 + c3) + c4)) - Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2) diff --git a/tests/coverage/branch/guard.coverage b/tests/coverage/branch/guard.coverage index f89b965b5d0f..465aefbf0665 100644 --- a/tests/coverage/branch/guard.coverage +++ b/tests/coverage/branch/guard.coverage @@ -17,7 +17,7 @@ LL| 1| println!("zero"); LL| 1| } LL| 3| Some(x) if x % 2 == 0 => { - ^2 + ^2 ^2 ------------------ | Branch (LL:20): [True: 2, False: 1] ------------------ diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map index a79232233013..86bfcadb1255 100644 --- a/tests/coverage/branch/if-let.cov-map +++ b/tests/coverage/branch/if-let.cov-map @@ -1,12 +1,13 @@ Function name: if_let::if_let -Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02] +Raw bytes (58): 0x[01, 01, 01, 01, 05, 0a, 01, 0c, 01, 00, 1f, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if-let.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14) -- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 12) to (start + 0, 19) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 12) to (start + 0, 19) true = (c0 - c1) false = c1 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18) @@ -15,41 +16,53 @@ Number of file 0 mappings: 7 - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 2, 6) = (c0 - c1) - Code(Counter(1)) at (prev + 2, 12) to (start + 2, 6) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: if_let::if_let_chain -Raw bytes (74): 0x[01, 01, 08, 01, 05, 01, 1f, 05, 09, 01, 1f, 05, 09, 01, 1f, 05, 09, 05, 09, 0a, 01, 17, 01, 00, 33, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 16, 09, 01, 10, 00, 17, 16, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 16, 01, 05, 03, 06, 1f, 03, 0c, 02, 06, 01, 03, 05, 01, 02] +Raw bytes (102): 0x[01, 01, 0c, 01, 05, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 05, 09, 0e, 01, 17, 01, 00, 32, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 26, 09, 01, 10, 00, 17, 26, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 26, 01, 05, 03, 06, 26, 01, 09, 00, 0c, 26, 00, 0d, 00, 0e, 2f, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if-let.rs -Number of expressions: 8 +Number of expressions: 12 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add) +- expression 1 operands: lhs = Counter(0), rhs = Expression(11, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(0), rhs = Expression(7, Add) +- expression 3 operands: lhs = Counter(0), rhs = Expression(11, Add) - expression 4 operands: lhs = Counter(1), rhs = Counter(2) -- expression 5 operands: lhs = Counter(0), rhs = Expression(7, Add) +- expression 5 operands: lhs = Counter(0), rhs = Expression(11, Add) - expression 6 operands: lhs = Counter(1), rhs = Counter(2) -- expression 7 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 51) +- expression 7 operands: lhs = Counter(0), rhs = Expression(11, Add) +- expression 8 operands: lhs = Counter(1), rhs = Counter(2) +- expression 9 operands: lhs = Counter(0), rhs = Expression(11, Add) +- expression 10 operands: lhs = Counter(1), rhs = Counter(2) +- expression 11 operands: lhs = Counter(1), rhs = Counter(2) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 50) - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 1, 12) to (start + 0, 19) true = (c0 - c1) false = c1 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18) = (c0 - c1) - Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) -- Branch { true: Expression(5, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23) +- Branch { true: Expression(9, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23) true = (c0 - (c1 + c2)) false = c2 -- Code(Expression(5, Sub)) at (prev + 0, 21) to (start + 0, 22) +- Code(Expression(9, Sub)) at (prev + 0, 21) to (start + 0, 22) = (c0 - (c1 + c2)) - Code(Expression(0, Sub)) at (prev + 0, 26) to (start + 0, 27) = (c0 - c1) -- Code(Expression(5, Sub)) at (prev + 1, 5) to (start + 3, 6) +- Code(Expression(9, Sub)) at (prev + 1, 5) to (start + 3, 6) = (c0 - (c1 + c2)) -- Code(Expression(7, Add)) at (prev + 3, 12) to (start + 2, 6) +- Code(Expression(9, Sub)) at (prev + 1, 9) to (start + 0, 12) + = (c0 - (c1 + c2)) +- Code(Expression(9, Sub)) at (prev + 0, 13) to (start + 0, 14) + = (c0 - (c1 + c2)) +- Code(Expression(11, Add)) at (prev + 2, 12) to (start + 2, 6) = (c1 + c2) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map index 64b13fcfaa1e..09a014ce8a1a 100644 --- a/tests/coverage/branch/if.cov-map +++ b/tests/coverage/branch/if.cov-map @@ -1,14 +1,15 @@ Function name: if::branch_and -Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (59): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 2b, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 43, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -23,7 +24,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::branch_not -Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (126): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 14, 01, 0c, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 7 @@ -34,13 +35,15 @@ Number of expressions: 7 - expression 4 operands: lhs = Counter(0), rhs = Counter(3) - expression 5 operands: lhs = Counter(0), rhs = Counter(4) - expression 6 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 18 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9) +Number of file 0 mappings: 20 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) -- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 8) to (start + 0, 10) @@ -68,7 +71,7 @@ Number of file 0 mappings: 18 Highest counter ID seen: c4 Function name: if::branch_not_as -Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 0e, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (95): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0f, 01, 1d, 01, 00, 1a, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 5 @@ -77,9 +80,10 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(3) - expression 4 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 20) +Number of file 0 mappings: 15 +- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 20) - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 0, 8) to (start + 0, 20) true = (c0 - c1) false = c1 @@ -104,7 +108,7 @@ Number of file 0 mappings: 14 Highest counter ID seen: c3 Function name: if::branch_or -Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 09, 01, 35, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 6 @@ -114,9 +118,10 @@ Number of expressions: 6 - expression 3 operands: lhs = Counter(1), rhs = Counter(2) - expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add) - expression 5 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 53, 1) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map index b01ca5c94dff..9ec7c9a7f42b 100644 --- a/tests/coverage/branch/lazy-boolean.cov-map +++ b/tests/coverage/branch/lazy-boolean.cov-map @@ -1,40 +1,46 @@ Function name: lazy_boolean::branch_and -Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 13, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/lazy-boolean.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: lazy_boolean::branch_or -Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/lazy-boolean.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) - Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: lazy_boolean::chain -Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02] +Raw bytes (161): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 17, 01, 24, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/lazy-boolean.rs Number of expressions: 15 @@ -53,9 +59,10 @@ Number of expressions: 15 - expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add) - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(6) - expression 14 operands: lhs = Counter(4), rhs = Counter(5) -Number of file 0 mappings: 19 -- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10) +Number of file 0 mappings: 23 +- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18) true = c1 @@ -69,7 +76,8 @@ Number of file 0 mappings: 19 true = c3 false = (c2 - c3) - Code(Counter(3)) at (prev + 0, 40) to (start + 0, 45) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18) - Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18) @@ -87,11 +95,13 @@ Number of file 0 mappings: 19 false = (c0 - ((c4 + c5) + c6)) - Code(Expression(12, Sub)) at (prev + 0, 40) to (start + 0, 45) = (c0 - ((c4 + c5) + c6)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c6 Function name: lazy_boolean::nested_mixed -Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02] +Raw bytes (157): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 17, 01, 31, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/lazy-boolean.rs Number of expressions: 13 @@ -108,9 +118,10 @@ Number of expressions: 13 - expression 10 operands: lhs = Counter(0), rhs = Counter(5) - expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add) - expression 12 operands: lhs = Counter(5), rhs = Counter(6) -Number of file 0 mappings: 19 -- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10) +Number of file 0 mappings: 23 +- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19) true = c1 @@ -127,7 +138,8 @@ Number of file 0 mappings: 19 false = ((c1 + c2) - c3) - Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51) = ((c1 + c2) - c3) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19) - Branch { true: Counter(4), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19) @@ -143,6 +155,8 @@ Number of file 0 mappings: 19 true = c6 false = (c0 - (c5 + c6)) - Code(Counter(6)) at (prev + 0, 44) to (start + 0, 51) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c6 diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map index 2af5e919f4c9..61bedbfbff0c 100644 --- a/tests/coverage/branch/let-else.cov-map +++ b/tests/coverage/branch/let-else.cov-map @@ -1,19 +1,24 @@ Function name: let_else::let_else -Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0a, 01, 01, 01, 00, 02] +Raw bytes (63): 0x[01, 01, 01, 01, 05, 0b, 01, 0c, 01, 00, 21, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 13, 05, 01, 09, 00, 0f, 02, 03, 05, 00, 08, 02, 00, 09, 00, 0a, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/let-else.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14) -- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 9) to (start + 0, 16) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 9) to (start + 0, 16) true = (c0 - c1) false = c1 - Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15) = (c0 - c1) - Code(Counter(0)) at (prev + 0, 19) to (start + 0, 24) -- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 15) -- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 10) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 19) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15) +- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 8) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 0, 9) to (start + 0, 10) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map index 3f753f14eb5b..a2ed0d84ed61 100644 --- a/tests/coverage/branch/match-arms.cov-map +++ b/tests/coverage/branch/match-arms.cov-map @@ -1,5 +1,5 @@ Function name: match_arms::guards -Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 0e, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 28, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 28, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 28, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 28, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 15, 01, 03, 05, 01, 02] +Raw bytes (158): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 1a, 01, 30, 01, 00, 23, 01, 01, 05, 00, 0e, 21, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 20, 05, 02, 00, 17, 00, 1b, 05, 00, 1a, 00, 1b, 05, 00, 1f, 00, 26, 05, 00, 27, 00, 28, 09, 01, 11, 00, 12, 20, 09, 06, 00, 17, 00, 1b, 09, 00, 1a, 00, 1b, 09, 00, 1f, 00, 26, 09, 00, 27, 00, 28, 0d, 01, 11, 00, 12, 20, 0d, 0a, 00, 17, 00, 1b, 0d, 00, 1a, 00, 1b, 0d, 00, 1f, 00, 26, 0d, 00, 27, 00, 28, 11, 01, 11, 00, 12, 20, 11, 0e, 00, 17, 00, 1b, 11, 00, 1a, 00, 1b, 11, 00, 1f, 00, 26, 11, 00, 27, 00, 28, 12, 01, 0e, 00, 15, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/match-arms.rs Number of expressions: 8 @@ -11,70 +11,103 @@ Number of expressions: 8 - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(4) - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3) - expression 7 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 12 -- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 14) -- Code(Counter(8)) at (prev + 3, 11) to (start + 0, 16) -- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 40) +Number of file 0 mappings: 26 +- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 35) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27) true = c1 false = (c5 - c1) -- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 40) +- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 38) +- Code(Counter(1)) at (prev + 0, 39) to (start + 0, 40) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 27) true = c2 false = (c6 - c2) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 40) +- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 27) +- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 38) +- Code(Counter(2)) at (prev + 0, 39) to (start + 0, 40) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) - Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 23) to (start + 0, 27) true = c3 false = (c7 - c3) -- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 40) +- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 27) +- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 38) +- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 40) +- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18) - Branch { true: Counter(4), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 27) true = c4 false = (c8 - c4) +- Code(Counter(4)) at (prev + 0, 26) to (start + 0, 27) +- Code(Counter(4)) at (prev + 0, 31) to (start + 0, 38) +- Code(Counter(4)) at (prev + 0, 39) to (start + 0, 40) - Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 21) = (c0 - (((c1 + c2) + c3) + c4)) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c8 Function name: match_arms::match_arms -Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 20, 09, 01, 11, 00, 20, 0d, 01, 11, 00, 20, 02, 01, 11, 00, 20, 01, 03, 05, 01, 02] +Raw bytes (95): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 11, 01, 18, 01, 00, 1b, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 05, 00, 17, 00, 1e, 05, 00, 1f, 00, 20, 09, 01, 11, 00, 12, 09, 00, 17, 00, 1e, 09, 00, 1f, 00, 20, 0d, 01, 11, 00, 12, 0d, 00, 17, 00, 1e, 0d, 00, 1f, 00, 20, 02, 01, 11, 00, 12, 02, 00, 17, 00, 1e, 02, 00, 1f, 00, 20, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/match-arms.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16) -- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 32) -- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 32) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 32) -- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 32) +Number of file 0 mappings: 17 +- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 27) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 32) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(2)) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 32) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 32) +- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 18) = (c0 - ((c1 + c2) + c3)) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 30) + = (c0 - ((c1 + c2) + c3)) +- Code(Expression(0, Sub)) at (prev + 0, 31) to (start + 0, 32) + = (c0 - ((c1 + c2) + c3)) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: match_arms::or_patterns -Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2d, 01, 03, 05, 01, 02] +Raw bytes (79): 0x[01, 01, 05, 05, 09, 01, 0b, 03, 0d, 01, 03, 01, 03, 0d, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2b, 03, 00, 2c, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 12, 00, 24, 00, 2b, 12, 00, 2c, 00, 2d, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/match-arms.rs -Number of expressions: 4 +Number of expressions: 5 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 3 operands: lhs = Counter(0), rhs = Expression(0, Add) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16) +- expression 4 operands: lhs = Counter(0), rhs = Expression(0, Add) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16) - Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18) - Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31) -- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 45) +- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 43) + = (c1 + c2) +- Code(Expression(0, Add)) at (prev + 0, 44) to (start + 0, 45) = (c1 + c2) - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) - Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31) = (c0 - ((c1 + c2) + c3)) -- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 45) +- Code(Expression(4, Sub)) at (prev + 0, 36) to (start + 0, 43) = (c0 - (c1 + c2)) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Expression(4, Sub)) at (prev + 0, 44) to (start + 0, 45) + = (c0 - (c1 + c2)) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map index dd05ae4e345f..a88e89523ae2 100644 --- a/tests/coverage/branch/match-trivial.cov-map +++ b/tests/coverage/branch/match-trivial.cov-map @@ -1,19 +1,24 @@ Function name: match_trivial::_uninhabited (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 0e] -Number of files: 1 -- file 0 => $DIR/match-trivial.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 22, 1) to (start + 1, 14) -Highest counter ID seen: (none) - -Function name: match_trivial::trivial -Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 0e, 01, 03, 0b, 05, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 16, 01, 00, 20, 00, 01, 05, 00, 0e] Number of files: 1 - file 0 => $DIR/match-trivial.rs Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 11) to (start + 5, 2) +- Code(Zero) at (prev + 22, 1) to (start + 0, 32) +- Code(Zero) at (prev + 1, 5) to (start + 0, 14) +Highest counter ID seen: (none) + +Function name: match_trivial::trivial +Raw bytes (34): 0x[01, 01, 00, 06, 01, 1e, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 0c, 01, 01, 1b, 00, 22, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/match-trivial.rs +Number of expressions: 0 +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 27) to (start + 0, 34) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/branch/match-trivial.coverage b/tests/coverage/branch/match-trivial.coverage index 4ffb172e1b67..6e7bf2d29abc 100644 --- a/tests/coverage/branch/match-trivial.coverage +++ b/tests/coverage/branch/match-trivial.coverage @@ -32,8 +32,8 @@ LL| | LL| 1| match x { LL| 1| Trivial::Value => consume("trivial"), - LL| 1| } - LL| 1| + LL| | } + LL| | LL| 1| consume("done"); LL| 1|} LL| | diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map index d28e6a580085..4f893cba1f81 100644 --- a/tests/coverage/branch/no-mir-spans.cov-map +++ b/tests/coverage/branch/no-mir-spans.cov-map @@ -1,31 +1,31 @@ Function name: no_mir_spans::while_cond -Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 11, 20, 02, 01, 04, 0b, 00, 10] +Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 10, 20, 02, 01, 04, 0b, 00, 10] Number of files: 1 - file 0 => $DIR/no-mir-spans.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 17) +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 16) - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 16) true = (c1 - c0) false = c0 Highest counter ID seen: c0 Function name: no_mir_spans::while_cond_not -Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 15, 20, 02, 01, 04, 0b, 00, 14] +Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 14, 20, 02, 01, 04, 0b, 00, 14] Number of files: 1 - file 0 => $DIR/no-mir-spans.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 21) +- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 20) - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 20) true = (c1 - c0) false = c0 Highest counter ID seen: c0 Function name: no_mir_spans::while_op_and -Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 13, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19] +Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19] Number of files: 1 - file 0 => $DIR/no-mir-spans.rs Number of expressions: 4 @@ -34,7 +34,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 18) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16) true = c1 false = (c2 - c1) @@ -44,7 +44,7 @@ Number of file 0 mappings: 3 Highest counter ID seen: c1 Function name: no_mir_spans::while_op_or -Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19] +Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 11, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19] Number of files: 1 - file 0 => $DIR/no-mir-spans.rs Number of expressions: 3 @@ -52,7 +52,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 17) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16) true = c1 false = (c2 - c1) diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map index e5fda26822e2..767a7e46495f 100644 --- a/tests/coverage/branch/while.cov-map +++ b/tests/coverage/branch/while.cov-map @@ -1,12 +1,14 @@ Function name: while::while_cond -Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 0c, 01, 00, 10, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16) - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 16) true = (c1 - c0) @@ -17,14 +19,16 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: while::while_cond_not -Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 15, 01, 00, 14, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 20) - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 20) true = (c1 - c0) @@ -35,7 +39,7 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: while::while_op_and -Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02] +Raw bytes (78): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 0c, 01, 1e, 01, 00, 12, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while.rs Number of expressions: 5 @@ -44,10 +48,14 @@ Number of expressions: 5 - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(1) - expression 3 operands: lhs = Counter(0), rhs = Counter(2) - expression 4 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16) true = c2 false = (c1 - c2) @@ -61,7 +69,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: while::while_op_or -Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02] +Raw bytes (76): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 0c, 01, 29, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while.rs Number of expressions: 4 @@ -69,10 +77,14 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 14) -- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16) true = c2 false = (c1 - c2) diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 096be9ea78a0..5f7e4ce58e97 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -1,18 +1,56 @@ Function name: closure::main -Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0d, 1b, 01, 1a, 05, 02, 0a, 01, 0c, 05, 11, 1b, 01, 1e, 05, 02, 0a, 01, 0c, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02] +Raw bytes (336): 0x[01, 01, 01, 01, 05, 42, 01, 09, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 1c, 01, 02, 09, 00, 18, 01, 00, 1b, 00, 43, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 3b, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 04, 05, 00, 10, 01, 00, 13, 00, 17, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 17, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 05, 09, 00, 16, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 28, 01, 02, 09, 00, 1a, 01, 01, 0e, 00, 12, 01, 01, 0e, 00, 11, 01, 02, 0d, 00, 1a, 01, 02, 0e, 00, 15, 01, 04, 09, 00, 18, 01, 0c, 09, 00, 16, 01, 00, 19, 00, 1b, 01, 01, 09, 00, 1e, 01, 03, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 05, 01, 09, 00, 30, 02, 03, 05, 00, 06, 01, 01, 05, 00, 28, 01, 01, 05, 00, 46, 01, 01, 05, 00, 43, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 24 -- Code(Counter(0)) at (prev + 9, 1) to (start + 13, 27) -- Code(Counter(0)) at (prev + 26, 5) to (start + 2, 10) -- Code(Counter(0)) at (prev + 12, 5) to (start + 17, 27) -- Code(Counter(0)) at (prev + 30, 5) to (start + 2, 10) -- Code(Counter(0)) at (prev + 12, 5) to (start + 12, 22) -- Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24) -- Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30) -- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41) +Number of file 0 mappings: 66 +- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 28) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 24) +- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27) +- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 59) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27) +- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 40) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 17) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 21) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 24) +- Code(Counter(0)) at (prev + 12, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 30) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 41) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 45) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 36) - Code(Counter(0)) at (prev + 5, 9) to (start + 0, 36) @@ -27,238 +65,277 @@ Number of file 0 mappings: 24 - Code(Counter(0)) at (prev + 8, 9) to (start + 0, 68) - Code(Counter(0)) at (prev + 10, 8) to (start + 0, 16) - Code(Counter(1)) at (prev + 0, 17) to (start + 4, 6) -- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 48) +- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 40) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 70) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: closure::main::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 28, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 1 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 40, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20) +- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10) +- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) + = (c0 - c1) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c1 + +Function name: closure::main::{closure#10} (unused) +Raw bytes (25): 0x[01, 01, 00, 04, 00, 9b, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 155, 7) to (start + 0, 8) +- Code(Zero) at (prev + 0, 9) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 0, 30) +- Code(Zero) at (prev + 0, 32) to (start + 0, 33) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#11} (unused) +Raw bytes (25): 0x[01, 01, 00, 04, 00, 9f, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 159, 7) to (start + 0, 8) +- Code(Zero) at (prev + 0, 9) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 0, 30) +- Code(Zero) at (prev + 0, 32) to (start + 0, 33) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#12} (unused) +Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 0a, 00, 16] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 167, 10) to (start + 0, 22) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#13} (unused) +Raw bytes (10): 0x[01, 01, 00, 01, 00, ad, 01, 11, 00, 1d] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 173, 17) to (start + 0, 29) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#14} +Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, b4, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 40, 5) to (start + 2, 20) -- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6) -Highest counter ID seen: c1 - -Function name: closure::main::{closure#10} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 155, 7) to (start + 0, 33) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#11} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 9f, 01, 07, 00, 21] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 159, 7) to (start + 0, 33) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#12} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 01, 00, 17] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 167, 1) to (start + 0, 23) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#13} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, ac, 01, 0d, 02, 0e] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 172, 13) to (start + 2, 14) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#14} -Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 1 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 179, 13) to (start + 2, 27) -- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37) +- Code(Counter(0)) at (prev + 180, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) Highest counter ID seen: c1 Function name: closure::main::{closure#15} -Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] +Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 +Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 187, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) -- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) Highest counter ID seen: c1 Function name: closure::main::{closure#16} -Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33] +Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, c6, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 197, 13) to (start + 2, 27) -- Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 198, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) Highest counter ID seen: c1 Function name: closure::main::{closure#17} -Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] +Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 +Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 205, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) -- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37) - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) Highest counter ID seen: c1 Function name: closure::main::{closure#18} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 19, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28) -- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 25, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34) +- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28) +- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18) - Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31) +- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) Highest counter ID seen: c1 Function name: closure::main::{closure#19} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 43, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 67, 13) to (start + 2, 28) -- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 67, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34) +- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28) +- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18) - Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14) +- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31) +- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) Highest counter ID seen: c1 Function name: closure::main::{closure#1} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 52, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 52, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 82, 5) to (start + 2, 20) -- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 82, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20) +- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: closure::main::{closure#2} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 68, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 68, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 11, 00, 17, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 104, 5) to (start + 2, 20) -- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 104, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20) +- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: closure::main::{closure#3} (unused) -Raw bytes (25): 0x[01, 01, 00, 04, 00, 81, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 01, 06] +Raw bytes (40): 0x[01, 01, 00, 07, 00, 81, 01, 05, 00, 06, 00, 01, 0c, 00, 14, 00, 00, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 00, 23, 00, 00, 24, 00, 2c, 00, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 7 +- Code(Zero) at (prev + 129, 5) to (start + 0, 6) +- Code(Zero) at (prev + 1, 12) to (start + 0, 20) +- Code(Zero) at (prev + 0, 21) to (start + 2, 10) +- Code(Zero) at (prev + 2, 9) to (start + 0, 10) +- Code(Zero) at (prev + 1, 9) to (start + 0, 35) +- Code(Zero) at (prev + 0, 36) to (start + 0, 44) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#5} +Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 46, 00, 4e] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 140, 70) to (start + 0, 78) +Highest counter ID seen: c0 + +Function name: closure::main::{closure#6} +Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 4a, 00, 56] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 141, 74) to (start + 0, 86) +Highest counter ID seen: c0 + +Function name: closure::main::{closure#7} (unused) +Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 44, 00, 50] +Number of files: 1 +- file 0 => $DIR/closure.rs +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 142, 68) to (start + 0, 80) +Highest counter ID seen: (none) + +Function name: closure::main::{closure#8} (unused) +Raw bytes (25): 0x[01, 01, 00, 04, 00, 93, 01, 3b, 00, 3c, 00, 00, 3d, 00, 45, 00, 00, 46, 00, 52, 00, 00, 54, 00, 55] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Zero) at (prev + 129, 5) to (start + 1, 20) -- Code(Zero) at (prev + 1, 21) to (start + 2, 10) -- Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Zero) at (prev + 1, 9) to (start + 1, 6) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#4} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 89, 01, 35, 00, 43] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 137, 53) to (start + 0, 67) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#5} -Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 3d, 00, 4f] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 140, 61) to (start + 0, 79) -Highest counter ID seen: c0 - -Function name: closure::main::{closure#6} -Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 41, 00, 57] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 141, 65) to (start + 0, 87) -Highest counter ID seen: c0 - -Function name: closure::main::{closure#7} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 3b, 00, 51] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 142, 59) to (start + 0, 81) -Highest counter ID seen: (none) - -Function name: closure::main::{closure#8} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 93, 01, 3b, 00, 55] -Number of files: 1 -- file 0 => $DIR/closure.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 147, 59) to (start + 0, 85) +- Code(Zero) at (prev + 147, 59) to (start + 0, 60) +- Code(Zero) at (prev + 0, 61) to (start + 0, 69) +- Code(Zero) at (prev + 0, 70) to (start + 0, 82) +- Code(Zero) at (prev + 0, 84) to (start + 0, 85) Highest counter ID seen: (none) Function name: closure::main::{closure#9} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 00, 95, 01, 38, 02, 06] +Raw bytes (25): 0x[01, 01, 00, 04, 00, 95, 01, 38, 00, 39, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 149, 56) to (start + 2, 6) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 149, 56) to (start + 0, 57) +- Code(Zero) at (prev + 1, 9) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 0, 30) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage index 2deeb9806c4d..142852692289 100644 --- a/tests/coverage/closure.coverage +++ b/tests/coverage/closure.coverage @@ -7,18 +7,18 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; LL| 1| let is_false = !is_true; - LL| 1| + LL| | LL| 1| let mut some_string = Some(String::from("the string content")); LL| 1| println!( LL| 1| "The string or alt: {}" - LL| 1| , + LL| | , LL| 1| some_string - LL| 1| . + LL| | . LL| 1| unwrap_or_else LL| | ( LL| | || @@ -33,7 +33,7 @@ LL| | ); LL| | LL| 1| some_string = Some(String::from("the string content")); - LL| 1| let + LL| | let LL| 1| a LL| | = LL| | || @@ -46,21 +46,21 @@ LL| 0| }; LL| 1| println!( LL| 1| "The string or alt: {}" - LL| 1| , + LL| | , LL| 1| some_string - LL| 1| . + LL| | . LL| 1| unwrap_or_else - LL| 1| ( + LL| | ( LL| 1| a - LL| 1| ) - LL| 1| ); - LL| 1| + LL| | ) + LL| | ); + LL| | LL| 1| some_string = None; LL| 1| println!( LL| 1| "The string or alt: {}" - LL| 1| , + LL| | , LL| 1| some_string - LL| 1| . + LL| | . LL| 1| unwrap_or_else LL| | ( LL| | || @@ -75,7 +75,7 @@ LL| | ); LL| | LL| 1| some_string = None; - LL| 1| let + LL| | let LL| 1| a LL| | = LL| | || @@ -88,16 +88,16 @@ LL| 1| }; LL| 1| println!( LL| 1| "The string or alt: {}" - LL| 1| , + LL| | , LL| 1| some_string - LL| 1| . + LL| | . LL| 1| unwrap_or_else - LL| 1| ( + LL| | ( LL| 1| a - LL| 1| ) - LL| 1| ); - LL| 1| - LL| 1| let + LL| | ) + LL| | ); + LL| | + LL| | let LL| 1| quote_closure LL| | = LL| | |val| @@ -110,17 +110,17 @@ LL| 5| }; LL| 1| println!( LL| 1| "Repeated, quoted string: {:?}" - LL| 1| , + LL| | , LL| 1| std::iter::repeat("repeat me") LL| 1| .take(5) LL| 1| .map - LL| 1| ( + LL| | ( LL| 1| quote_closure - LL| 1| ) + LL| | ) LL| 1| .collect::>() - LL| 1| ); - LL| 1| - LL| 1| let + LL| | ); + LL| | + LL| | let LL| 1| _unused_closure LL| | = LL| | | @@ -135,22 +135,22 @@ LL| | LL| 1| let mut countdown = 10; LL| 1| let _short_unused_closure = | _unused_arg: u8 | countdown += 1; - ^0 LL| | LL| | LL| 1| let short_used_covered_closure_macro = | used_arg: u8 | println!("called"); LL| 1| let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called"); - ^0 + ^0 LL| 1| let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called"); - ^0 + ^0 LL| | LL| | LL| | LL| | LL| 1| let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") }; - ^0 + ^0^0 ^0 ^0 LL| | LL| 1| let _shortish_unused_closure = | _unused_arg: u8 | { + ^0 LL| 0| println!("not called") LL| 0| }; LL| | @@ -173,14 +173,14 @@ LL| | LL| 1| let _short_unused_closure_line_break_no_block2 = LL| | | _unused_arg: u8 | - LL| 0| println!( + LL| | println!( LL| 0| "not called" - LL| 0| ) + LL| | ) LL| | ; LL| | LL| 1| let short_used_not_covered_closure_line_break_no_block_embedded_branch = LL| | | _unused_arg: u8 | - LL| 0| println!( + LL| | println!( LL| 0| "not called: {}", LL| 0| if is_true { "check" } else { "me" } LL| | ) @@ -198,7 +198,7 @@ LL| | LL| 1| let short_used_covered_closure_line_break_no_block_embedded_branch = LL| | | _unused_arg: u8 | - LL| 1| println!( + LL| | println!( LL| 1| "not called: {}", LL| 1| if is_true { "check" } else { "me" } ^0 diff --git a/tests/coverage/closure_bug.cov-map b/tests/coverage/closure_bug.cov-map index 8355cbf352b3..a7087c69dcba 100644 --- a/tests/coverage/closure_bug.cov-map +++ b/tests/coverage/closure_bug.cov-map @@ -1,5 +1,5 @@ Function name: closure_bug::main -Raw bytes (97): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 11, 01, 07, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02] +Raw bytes (132): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 18, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 2d, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 05, 00, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 09, 00, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 0d, 00, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 11, 00, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_bug.rs Number of expressions: 4 @@ -7,38 +7,45 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(3) - expression 3 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 17 -- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 10) -- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 14) -- Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23) +Number of file 0 mappings: 24 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 45) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 23) - Code(Expression(0, Sub)) at (prev + 0, 22) to (start + 0, 23) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14) -- Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 23) - Code(Expression(1, Sub)) at (prev + 0, 22) to (start + 0, 23) = (c0 - c2) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14) -- Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 23) - Code(Expression(2, Sub)) at (prev + 0, 22) to (start + 0, 23) = (c0 - c3) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14) -- Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(4)) at (prev + 0, 15) to (start + 0, 23) - Code(Expression(3, Sub)) at (prev + 0, 22) to (start + 0, 23) = (c0 - c4) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c4 Function name: closure_bug::main::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 - file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 14, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 14, 12) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) = (c0 - c1) @@ -46,13 +53,13 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: closure_bug::main::{closure#1} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 - file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 23, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 23, 12) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) = (c0 - c1) @@ -60,13 +67,13 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: closure_bug::main::{closure#2} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 - file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 32, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 32, 12) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) = (c0 - c1) @@ -74,13 +81,13 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: closure_bug::main::{closure#3} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a] Number of files: 1 - file 0 => $DIR/closure_bug.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 41, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 41, 12) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) = (c0 - c1) diff --git a/tests/coverage/closure_bug.coverage b/tests/coverage/closure_bug.coverage index cc64470baa77..b85375d1850b 100644 --- a/tests/coverage/closure_bug.coverage +++ b/tests/coverage/closure_bug.coverage @@ -6,7 +6,7 @@ LL| |#[rustfmt::skip] LL| 1|fn main() { LL| 1| let truthy = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let a LL| | = LL| | | diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map index c624896a720a..3ab1d7f5fba8 100644 --- a/tests/coverage/closure_macro.cov-map +++ b/tests/coverage/closure_macro.cov-map @@ -1,41 +1,57 @@ Function name: closure_macro::load_configuration_files -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 1d, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_macro.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 56) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: closure_macro::main -Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] +Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 21, 01, 00, 24, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_macro.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 32) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32) +- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15) = (c0 - c1) -- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27) +- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52) - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) +- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31) = (c0 - c1) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11) + = (c0 - c1) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: closure_macro::main::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] +Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/closure_macro.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33) -- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) -- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 16, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24) +- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25) +- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39) +- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22) = (c0 - c1) - Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30) = (c0 - (c1 + c2)) diff --git a/tests/coverage/closure_macro.coverage b/tests/coverage/closure_macro.coverage index 00022bbff89f..b1d7a8327a4e 100644 --- a/tests/coverage/closure_macro.coverage +++ b/tests/coverage/closure_macro.coverage @@ -14,7 +14,7 @@ LL| |macro_rules! on_error { LL| | ($value:expr, $error_message:expr) => { LL| 0| $value.or_else(|e| { - LL| 0| // This closure, which is declared in a macro, should be instrumented. + LL| | // This closure, which is declared in a macro, should be instrumented. LL| 0| let message = format!($error_message, e); LL| 0| if message.len() > 0 { LL| 0| println!("{}", message); diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 77bf31de8bd8..b5f4cee0ec44 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -1,50 +1,66 @@ Function name: closure_macro_async::load_configuration_files -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 21, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_macro_async.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 56) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: closure_macro_async::test -Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2a] Number of files: 1 - file 0 => $DIR/closure_macro_async.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 42) Highest counter ID seen: c0 Function name: closure_macro_async::test::{closure#0} -Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] +Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 25, 2b, 00, 2c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_macro_async.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 32) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 37, 43) to (start + 0, 44) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32) +- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15) = (c0 - c1) -- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27) +- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52) - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) +- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31) = (c0 - c1) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11) + = (c0 - c1) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 14, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] +Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 14, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/closure_macro_async.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 20, 28) to (start + 3, 33) -- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) -- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 20, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24) +- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25) +- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30) +- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39) +- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22) = (c0 - c1) - Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30) = (c0 - (c1 + c2)) diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage index 1e1ffec9f761..7bfea3c9bb3b 100644 --- a/tests/coverage/closure_macro_async.coverage +++ b/tests/coverage/closure_macro_async.coverage @@ -18,7 +18,7 @@ LL| |macro_rules! on_error { LL| | ($value:expr, $error_message:expr) => { LL| 0| $value.or_else(|e| { - LL| 0| // This closure, which is declared in a macro, should be instrumented. + LL| | // This closure, which is declared in a macro, should be instrumented. LL| 0| let message = format!($error_message, e); LL| 0| if message.len() > 0 { LL| 0| println!("{}", message); diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map index c75119019fc8..f665d93e6e1c 100644 --- a/tests/coverage/closure_unit_return.cov-map +++ b/tests/coverage/closure_unit_return.cov-map @@ -1,38 +1,49 @@ Function name: closure_unit_return::explicit_unit -Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 07, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 01, 05, 00, 07, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16) -- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9) +- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: closure_unit_return::explicit_unit::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 08, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 8, 22) to (start + 2, 6) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 8, 22) to (start + 0, 23) +- Code(Zero) at (prev + 1, 9) to (start + 0, 11) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) Function name: closure_unit_return::implicit_unit -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16) -- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9) +- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17) +- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: closure_unit_return::implicit_unit::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 11, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure_unit_return.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 17, 22) to (start + 2, 6) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 17, 22) to (start + 0, 23) +- Code(Zero) at (prev + 1, 9) to (start + 0, 11) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) diff --git a/tests/coverage/closure_unit_return.coverage b/tests/coverage/closure_unit_return.coverage index 5e57e0db1600..02ea63b6dc39 100644 --- a/tests/coverage/closure_unit_return.coverage +++ b/tests/coverage/closure_unit_return.coverage @@ -6,6 +6,7 @@ LL| | LL| 1|fn explicit_unit() { LL| 1| let closure = || { + ^0 LL| 0| (); LL| 0| }; LL| | @@ -15,11 +16,12 @@ LL| | LL| 1|fn implicit_unit() { LL| 1| let closure = || { + ^0 LL| 0| (); LL| 0| }; LL| | LL| 1| drop(closure); - LL| 1| // implicit return of `()` + LL| | // implicit return of `()` LL| 1|} LL| | LL| |#[coverage(off)] diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map index 1bcf045b8942..fda5dd1b97d1 100644 --- a/tests/coverage/condition/conditions.cov-map +++ b/tests/coverage/condition/conditions.cov-map @@ -1,5 +1,5 @@ Function name: conditions::assign_3_and_or -Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1c, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (75): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0b, 01, 1c, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 5 @@ -8,8 +8,8 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) - expression 4 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 47) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 46) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -24,11 +24,13 @@ Number of file 0 mappings: 9 - Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24) true = c3 false = (c0 - (c2 + c3)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: conditions::assign_3_or_and -Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 17, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (73): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0b, 01, 17, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 4 @@ -36,8 +38,8 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 47) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 46) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -52,18 +54,20 @@ Number of file 0 mappings: 9 - Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24) true = c3 false = (c2 - c3) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: conditions::assign_and -Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0d, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (57): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 0d, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 32) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -73,19 +77,21 @@ Number of file 0 mappings: 7 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c1 - c2) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: conditions::assign_or -Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 12, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (59): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 09, 01, 12, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 32) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 31) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -96,27 +102,32 @@ Number of file 0 mappings: 7 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c0 - (c1 + c2)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: conditions::foo -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: conditions::func_call -Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] +Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 31) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8) - Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 9) to (start + 0, 10) @@ -130,11 +141,16 @@ Number of file 0 mappings: 7 Highest counter ID seen: c2 Function name: conditions::simple_assign -Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 08, 01, 00, 1a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map index 86a317948132..29d9604085ed 100644 --- a/tests/coverage/conditions.cov-map +++ b/tests/coverage/conditions.cov-map @@ -1,8 +1,8 @@ Function name: conditions::main -Raw bytes (533): 0x[01, 01, 47, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 97, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 97, 01, 15, 0d, 11, 19, 45, 19, 8f, 01, 45, 49, 8f, 01, 4d, 45, 49, 19, 8b, 01, 8f, 01, 4d, 45, 49, 97, 01, db, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, db, 01, 1d, 15, 19, 21, 39, 21, d3, 01, 39, 3d, d3, 01, 41, 39, 3d, 21, cf, 01, d3, 01, 41, 39, 3d, db, 01, 97, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, 97, 02, 25, 1d, 21, 29, 2d, 29, 8f, 02, 2d, 31, 8f, 02, 35, 2d, 31, 29, 8b, 02, 8f, 02, 35, 2d, 31, 97, 02, 9b, 02, 1d, 21, 25, 29, 44, 01, 03, 01, 02, 0c, 01, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 01, 0a, 06, 02, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 01, 12, 2a, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 03, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 97, 01, 03, 08, 00, 0c, 97, 01, 01, 0d, 01, 10, 97, 01, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 97, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 6a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 72, 00, 21, 00, 2e, 76, 00, 32, 00, 40, 8b, 01, 00, 41, 02, 0e, 86, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 92, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, db, 01, 02, 09, 01, 0c, db, 01, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 97, 02, 02, 09, 00, 0a, db, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, ae, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, b6, 01, 00, 1d, 00, 2a, ba, 01, 00, 2e, 00, 3c, cf, 01, 00, 3d, 02, 0a, ca, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, d6, 01, 02, 0d, 02, 0f, 9b, 02, 05, 09, 00, 0a, 97, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, ea, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, f2, 01, 00, 1d, 00, 2a, f6, 01, 00, 2e, 00, 3c, 8b, 02, 00, 3d, 02, 0a, 86, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, 92, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] +Raw bytes (656): 0x[01, 01, 57, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 9f, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 9f, 01, 15, 0d, 11, 19, 45, 19, 97, 01, 45, 49, 97, 01, 4d, 45, 49, 19, 93, 01, 97, 01, 4d, 45, 49, 9f, 01, 9b, 02, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, 9b, 02, 1d, 15, 19, 21, 39, 21, e3, 01, 39, 3d, e3, 01, 41, 39, 3d, 21, df, 01, e3, 01, 41, 39, 3d, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, d7, 02, 25, 1d, 21, 29, 2d, 29, cf, 02, 2d, 31, cf, 02, 35, 2d, 31, 29, cb, 02, cf, 02, 35, 2d, 31, d7, 02, db, 02, 1d, 21, 25, 29, 53, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 2a, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 9f, 01, 01, 0d, 00, 1a, 9f, 01, 00, 1d, 00, 1e, 9f, 01, 01, 0c, 00, 10, 9f, 01, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 9f, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 72, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 7a, 00, 21, 00, 2e, 7e, 00, 32, 00, 40, 93, 01, 00, 41, 02, 0e, 8e, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 9a, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 9b, 02, 02, 09, 00, 16, 9b, 02, 00, 19, 00, 1a, 9b, 02, 01, 08, 00, 0c, 9b, 02, 00, 0d, 02, 06, 00, 02, 05, 00, 06, d7, 02, 02, 09, 00, 0a, 9b, 02, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, be, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, c6, 01, 00, 1d, 00, 2a, ca, 01, 00, 2e, 00, 3c, df, 01, 00, 3d, 02, 0a, da, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, 96, 02, 02, 0d, 00, 20, 96, 02, 00, 23, 00, 2c, 96, 02, 01, 09, 00, 11, 96, 02, 00, 12, 00, 1b, 96, 02, 01, 09, 00, 0f, db, 02, 03, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, aa, 02, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, b2, 02, 00, 1d, 00, 2a, b6, 02, 00, 2e, 00, 3c, cb, 02, 00, 3d, 02, 0a, c6, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, d2, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs -Number of expressions: 71 +Number of expressions: 87 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(2), rhs = Counter(23) @@ -23,66 +23,86 @@ Number of expressions: 71 - expression 17 operands: lhs = Counter(4), rhs = Expression(18, Add) - expression 18 operands: lhs = Expression(19, Add), rhs = Counter(22) - expression 19 operands: lhs = Counter(20), rhs = Counter(21) -- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(37, Add) +- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(39, Add) - expression 21 operands: lhs = Counter(3), rhs = Counter(4) - expression 22 operands: lhs = Counter(3), rhs = Counter(4) - expression 23 operands: lhs = Counter(3), rhs = Counter(4) - expression 24 operands: lhs = Counter(3), rhs = Counter(4) - expression 25 operands: lhs = Counter(3), rhs = Counter(4) -- expression 26 operands: lhs = Expression(37, Add), rhs = Counter(5) +- expression 26 operands: lhs = Counter(3), rhs = Counter(4) - expression 27 operands: lhs = Counter(3), rhs = Counter(4) -- expression 28 operands: lhs = Counter(6), rhs = Counter(17) -- expression 29 operands: lhs = Counter(6), rhs = Expression(35, Add) -- expression 30 operands: lhs = Counter(17), rhs = Counter(18) -- expression 31 operands: lhs = Expression(35, Add), rhs = Counter(19) +- expression 28 operands: lhs = Expression(39, Add), rhs = Counter(5) +- expression 29 operands: lhs = Counter(3), rhs = Counter(4) +- expression 30 operands: lhs = Counter(6), rhs = Counter(17) +- expression 31 operands: lhs = Counter(6), rhs = Expression(37, Add) - expression 32 operands: lhs = Counter(17), rhs = Counter(18) -- expression 33 operands: lhs = Counter(6), rhs = Expression(34, Add) -- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(19) -- expression 35 operands: lhs = Counter(17), rhs = Counter(18) -- expression 36 operands: lhs = Expression(37, Add), rhs = Expression(54, Add) -- expression 37 operands: lhs = Counter(3), rhs = Counter(4) -- expression 38 operands: lhs = Counter(5), rhs = Counter(6) -- expression 39 operands: lhs = Counter(5), rhs = Counter(6) +- expression 33 operands: lhs = Expression(37, Add), rhs = Counter(19) +- expression 34 operands: lhs = Counter(17), rhs = Counter(18) +- expression 35 operands: lhs = Counter(6), rhs = Expression(36, Add) +- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(19) +- expression 37 operands: lhs = Counter(17), rhs = Counter(18) +- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(70, Add) +- expression 39 operands: lhs = Counter(3), rhs = Counter(4) - expression 40 operands: lhs = Counter(5), rhs = Counter(6) -- expression 41 operands: lhs = Counter(7), rhs = Counter(8) +- expression 41 operands: lhs = Counter(5), rhs = Counter(6) - expression 42 operands: lhs = Counter(5), rhs = Counter(6) -- expression 43 operands: lhs = Expression(54, Add), rhs = Counter(7) +- expression 43 operands: lhs = Counter(5), rhs = Counter(6) - expression 44 operands: lhs = Counter(5), rhs = Counter(6) -- expression 45 operands: lhs = Counter(8), rhs = Counter(14) -- expression 46 operands: lhs = Counter(8), rhs = Expression(52, Add) -- expression 47 operands: lhs = Counter(14), rhs = Counter(15) -- expression 48 operands: lhs = Expression(52, Add), rhs = Counter(16) -- expression 49 operands: lhs = Counter(14), rhs = Counter(15) -- expression 50 operands: lhs = Counter(8), rhs = Expression(51, Add) -- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(16) -- expression 52 operands: lhs = Counter(14), rhs = Counter(15) -- expression 53 operands: lhs = Expression(54, Add), rhs = Expression(69, Add) -- expression 54 operands: lhs = Counter(5), rhs = Counter(6) -- expression 55 operands: lhs = Counter(7), rhs = Counter(8) -- expression 56 operands: lhs = Counter(9), rhs = Counter(10) -- expression 57 operands: lhs = Counter(7), rhs = Counter(8) -- expression 58 operands: lhs = Expression(69, Add), rhs = Counter(9) +- expression 45 operands: lhs = Counter(7), rhs = Counter(8) +- expression 46 operands: lhs = Counter(5), rhs = Counter(6) +- expression 47 operands: lhs = Expression(70, Add), rhs = Counter(7) +- expression 48 operands: lhs = Counter(5), rhs = Counter(6) +- expression 49 operands: lhs = Counter(8), rhs = Counter(14) +- expression 50 operands: lhs = Counter(8), rhs = Expression(56, Add) +- expression 51 operands: lhs = Counter(14), rhs = Counter(15) +- expression 52 operands: lhs = Expression(56, Add), rhs = Counter(16) +- expression 53 operands: lhs = Counter(14), rhs = Counter(15) +- expression 54 operands: lhs = Counter(8), rhs = Expression(55, Add) +- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(16) +- expression 56 operands: lhs = Counter(14), rhs = Counter(15) +- expression 57 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) +- expression 58 operands: lhs = Counter(5), rhs = Counter(6) - expression 59 operands: lhs = Counter(7), rhs = Counter(8) -- expression 60 operands: lhs = Counter(10), rhs = Counter(11) -- expression 61 operands: lhs = Counter(10), rhs = Expression(67, Add) -- expression 62 operands: lhs = Counter(11), rhs = Counter(12) -- expression 63 operands: lhs = Expression(67, Add), rhs = Counter(13) -- expression 64 operands: lhs = Counter(11), rhs = Counter(12) -- expression 65 operands: lhs = Counter(10), rhs = Expression(66, Add) -- expression 66 operands: lhs = Expression(67, Add), rhs = Counter(13) -- expression 67 operands: lhs = Counter(11), rhs = Counter(12) -- expression 68 operands: lhs = Expression(69, Add), rhs = Expression(70, Add) -- expression 69 operands: lhs = Counter(7), rhs = Counter(8) -- expression 70 operands: lhs = Counter(9), rhs = Counter(10) -Number of file 0 mappings: 68 -- Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12) -- Code(Counter(0)) at (prev + 2, 13) to (start + 2, 6) +- expression 60 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) +- expression 61 operands: lhs = Counter(5), rhs = Counter(6) +- expression 62 operands: lhs = Counter(7), rhs = Counter(8) +- expression 63 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) +- expression 64 operands: lhs = Counter(5), rhs = Counter(6) +- expression 65 operands: lhs = Counter(7), rhs = Counter(8) +- expression 66 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) +- expression 67 operands: lhs = Counter(5), rhs = Counter(6) +- expression 68 operands: lhs = Counter(7), rhs = Counter(8) +- expression 69 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) +- expression 70 operands: lhs = Counter(5), rhs = Counter(6) +- expression 71 operands: lhs = Counter(7), rhs = Counter(8) +- expression 72 operands: lhs = Counter(9), rhs = Counter(10) +- expression 73 operands: lhs = Counter(7), rhs = Counter(8) +- expression 74 operands: lhs = Expression(85, Add), rhs = Counter(9) +- expression 75 operands: lhs = Counter(7), rhs = Counter(8) +- expression 76 operands: lhs = Counter(10), rhs = Counter(11) +- expression 77 operands: lhs = Counter(10), rhs = Expression(83, Add) +- expression 78 operands: lhs = Counter(11), rhs = Counter(12) +- expression 79 operands: lhs = Expression(83, Add), rhs = Counter(13) +- expression 80 operands: lhs = Counter(11), rhs = Counter(12) +- expression 81 operands: lhs = Counter(10), rhs = Expression(82, Add) +- expression 82 operands: lhs = Expression(83, Add), rhs = Counter(13) +- expression 83 operands: lhs = Counter(11), rhs = Counter(12) +- expression 84 operands: lhs = Expression(85, Add), rhs = Expression(86, Add) +- expression 85 operands: lhs = Counter(7), rhs = Counter(8) +- expression 86 operands: lhs = Counter(9), rhs = Counter(10) +Number of file 0 mappings: 83 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10) = (c1 + c2) - Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29) -- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 10) -- Code(Expression(1, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 23) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) +- Code(Expression(1, Sub)) at (prev + 1, 15) to (start + 0, 28) = (c0 - c1) - Code(Counter(2)) at (prev + 1, 12) to (start + 0, 25) - Code(Expression(2, Sub)) at (prev + 0, 29) to (start + 0, 42) @@ -93,12 +113,17 @@ Number of file 0 mappings: 68 = ((c23 + c24) + c25) - Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c2 - ((c23 + c24) + c25)) -- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 18) -- Code(Expression(10, Sub)) at (prev + 3, 9) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 23) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 18) +- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - (c1 + c2)) -- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12) +- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 22) = (c1 + c2) -- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 2, 6) +- Code(Expression(0, Add)) at (prev + 0, 25) to (start + 0, 26) + = (c1 + c2) +- Code(Expression(0, Add)) at (prev + 1, 8) to (start + 0, 12) + = (c1 + c2) +- Code(Expression(0, Add)) at (prev + 0, 13) to (start + 2, 6) = (c1 + c2) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21) @@ -118,73 +143,89 @@ Number of file 0 mappings: 68 - Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23) - Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15) = ((c1 + c2) - (c3 + c4)) -- Code(Expression(37, Add)) at (prev + 3, 8) to (start + 0, 12) +- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12) = (c3 + c4) -- Code(Expression(37, Add)) at (prev + 1, 13) to (start + 1, 16) +- Code(Expression(39, Add)) at (prev + 1, 13) to (start + 0, 26) = (c3 + c4) -- Code(Expression(37, Add)) at (prev + 1, 17) to (start + 2, 10) +- Code(Expression(39, Add)) at (prev + 0, 29) to (start + 0, 30) + = (c3 + c4) +- Code(Expression(39, Add)) at (prev + 1, 12) to (start + 0, 16) + = (c3 + c4) +- Code(Expression(39, Add)) at (prev + 0, 17) to (start + 2, 10) = (c3 + c4) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(37, Add)) at (prev + 2, 12) to (start + 0, 25) +- Code(Expression(39, Add)) at (prev + 2, 12) to (start + 0, 25) = (c3 + c4) - Code(Counter(5)) at (prev + 0, 26) to (start + 2, 10) -- Code(Expression(26, Sub)) at (prev + 4, 17) to (start + 0, 30) +- Code(Expression(28, Sub)) at (prev + 4, 17) to (start + 0, 30) = ((c3 + c4) - c5) - Code(Counter(6)) at (prev + 1, 16) to (start + 0, 29) -- Code(Expression(28, Sub)) at (prev + 0, 33) to (start + 0, 46) +- Code(Expression(30, Sub)) at (prev + 0, 33) to (start + 0, 46) = (c6 - c17) -- Code(Expression(29, Sub)) at (prev + 0, 50) to (start + 0, 64) +- Code(Expression(31, Sub)) at (prev + 0, 50) to (start + 0, 64) = (c6 - (c17 + c18)) -- Code(Expression(34, Add)) at (prev + 0, 65) to (start + 2, 14) +- Code(Expression(36, Add)) at (prev + 0, 65) to (start + 2, 14) = ((c17 + c18) + c19) -- Code(Expression(33, Sub)) at (prev + 2, 13) to (start + 0, 14) +- Code(Expression(35, Sub)) at (prev + 2, 13) to (start + 0, 14) = (c6 - ((c17 + c18) + c19)) - Code(Counter(6)) at (prev + 1, 13) to (start + 0, 27) -- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19) +- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 19) = ((c3 + c4) - (c5 + c6)) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(54, Add)) at (prev + 2, 9) to (start + 1, 12) +- Code(Expression(70, Add)) at (prev + 2, 9) to (start + 0, 22) = (c5 + c6) -- Code(Expression(54, Add)) at (prev + 1, 13) to (start + 2, 6) +- Code(Expression(70, Add)) at (prev + 0, 25) to (start + 0, 26) + = (c5 + c6) +- Code(Expression(70, Add)) at (prev + 1, 8) to (start + 0, 12) + = (c5 + c6) +- Code(Expression(70, Add)) at (prev + 0, 13) to (start + 2, 6) = (c5 + c6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(69, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(85, Add)) at (prev + 2, 9) to (start + 0, 10) = (c7 + c8) -- Code(Expression(54, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(70, Add)) at (prev + 0, 16) to (start + 0, 29) = (c5 + c6) - Code(Counter(7)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(43, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(47, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c5 + c6) - c7) - Code(Counter(8)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(45, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(49, Sub)) at (prev + 0, 29) to (start + 0, 42) = (c8 - c14) -- Code(Expression(46, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(50, Sub)) at (prev + 0, 46) to (start + 0, 60) = (c8 - (c14 + c15)) -- Code(Expression(51, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(55, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c14 + c15) + c16) -- Code(Expression(50, Sub)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(54, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c8 - ((c14 + c15) + c16)) - Code(Counter(8)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(53, Sub)) at (prev + 2, 13) to (start + 2, 15) +- Code(Expression(69, Sub)) at (prev + 2, 13) to (start + 0, 32) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(70, Add)) at (prev + 5, 9) to (start + 0, 10) +- Code(Expression(69, Sub)) at (prev + 0, 35) to (start + 0, 44) + = ((c5 + c6) - (c7 + c8)) +- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 17) + = ((c5 + c6) - (c7 + c8)) +- Code(Expression(69, Sub)) at (prev + 0, 18) to (start + 0, 27) + = ((c5 + c6) - (c7 + c8)) +- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 15) + = ((c5 + c6) - (c7 + c8)) +- Code(Expression(86, Add)) at (prev + 3, 9) to (start + 0, 10) = (c9 + c10) -- Code(Expression(69, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29) = (c7 + c8) - Code(Counter(9)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(58, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(74, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c7 + c8) - c9) - Code(Counter(10)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(60, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(76, Sub)) at (prev + 0, 29) to (start + 0, 42) = (c10 - c11) -- Code(Expression(61, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(77, Sub)) at (prev + 0, 46) to (start + 0, 60) = (c10 - (c11 + c12)) -- Code(Expression(66, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(82, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c11 + c12) + c13) -- Code(Expression(65, Sub)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(81, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c10 - ((c11 + c12) + c13)) - Code(Counter(10)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(68, Sub)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(84, Sub)) at (prev + 2, 9) to (start + 0, 15) = ((c7 + c8) - (c9 + c10)) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c10 diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map index a8077a32df7d..1a839f19a0f5 100644 --- a/tests/coverage/continue.cov-map +++ b/tests/coverage/continue.cov-map @@ -1,75 +1,88 @@ Function name: continue::main -Raw bytes (198): 0x[01, 01, 16, 05, 01, 05, 0b, 01, 09, 0d, 01, 0d, 1f, 01, 11, 0d, 1f, 01, 11, 15, 01, 15, 2b, 01, 19, 1d, 01, 1d, 37, 01, 21, 25, 01, 25, 43, 01, 29, 25, 01, 2d, 01, 53, 2d, 01, 31, 2d, 01, 1e, 01, 03, 01, 03, 12, 05, 04, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 06, 02, 12, 04, 0e, 0d, 06, 0e, 00, 13, 0e, 01, 0f, 00, 16, 1a, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 1a, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 22, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 26, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 2e, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 32, 01, 0a, 01, 0e, 25, 03, 0e, 00, 13, 46, 01, 0f, 00, 16, 3e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 46, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 56, 01, 16, 02, 0e, 4e, 04, 11, 00, 16, 56, 03, 09, 00, 0e, 01, 02, 0d, 01, 02] +Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 2d, 01, 63, 2d, 01, 31, 2d, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 0d, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 25, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/continue.rs -Number of expressions: 22 +Number of expressions: 26 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) -- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) +- expression 1 operands: lhs = Counter(1), rhs = Expression(4, Add) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -- expression 3 operands: lhs = Counter(3), rhs = Counter(0) -- expression 4 operands: lhs = Counter(3), rhs = Expression(7, Add) -- expression 5 operands: lhs = Counter(0), rhs = Counter(4) -- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add) +- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) +- expression 4 operands: lhs = Counter(0), rhs = Counter(2) +- expression 5 operands: lhs = Counter(3), rhs = Counter(0) +- expression 6 operands: lhs = Counter(3), rhs = Expression(9, Add) - expression 7 operands: lhs = Counter(0), rhs = Counter(4) -- expression 8 operands: lhs = Counter(5), rhs = Counter(0) -- expression 9 operands: lhs = Counter(5), rhs = Expression(10, Add) -- expression 10 operands: lhs = Counter(0), rhs = Counter(6) -- expression 11 operands: lhs = Counter(7), rhs = Counter(0) -- expression 12 operands: lhs = Counter(7), rhs = Expression(13, Add) -- expression 13 operands: lhs = Counter(0), rhs = Counter(8) -- expression 14 operands: lhs = Counter(9), rhs = Counter(0) -- expression 15 operands: lhs = Counter(9), rhs = Expression(16, Add) -- expression 16 operands: lhs = Counter(0), rhs = Counter(10) -- expression 17 operands: lhs = Counter(9), rhs = Counter(0) -- expression 18 operands: lhs = Counter(11), rhs = Counter(0) -- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(11) -- expression 20 operands: lhs = Counter(0), rhs = Counter(12) -- expression 21 operands: lhs = Counter(11), rhs = Counter(0) -Number of file 0 mappings: 30 -- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18) -- Code(Counter(1)) at (prev + 4, 14) to (start + 0, 19) +- expression 8 operands: lhs = Counter(3), rhs = Expression(9, Add) +- expression 9 operands: lhs = Counter(0), rhs = Counter(4) +- expression 10 operands: lhs = Counter(5), rhs = Counter(0) +- expression 11 operands: lhs = Counter(5), rhs = Expression(12, Add) +- expression 12 operands: lhs = Counter(0), rhs = Counter(6) +- expression 13 operands: lhs = Counter(7), rhs = Counter(0) +- expression 14 operands: lhs = Counter(7), rhs = Expression(17, Add) +- expression 15 operands: lhs = Counter(0), rhs = Counter(8) +- expression 16 operands: lhs = Counter(7), rhs = Expression(17, Add) +- expression 17 operands: lhs = Counter(0), rhs = Counter(8) +- expression 18 operands: lhs = Counter(9), rhs = Counter(0) +- expression 19 operands: lhs = Counter(9), rhs = Expression(20, Add) +- expression 20 operands: lhs = Counter(0), rhs = Counter(10) +- expression 21 operands: lhs = Counter(9), rhs = Counter(0) +- expression 22 operands: lhs = Counter(11), rhs = Counter(0) +- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(11) +- expression 24 operands: lhs = Counter(0), rhs = Counter(12) +- expression 25 operands: lhs = Counter(11), rhs = Counter(0) +Number of file 0 mappings: 37 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c1 - c0) - Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25) -- Code(Expression(1, Sub)) at (prev + 2, 18) to (start + 4, 14) +- Code(Expression(3, Sub)) at (prev + 2, 18) to (start + 2, 14) = (c1 - (c0 + c2)) -- Code(Counter(3)) at (prev + 6, 14) to (start + 0, 19) -- Code(Expression(3, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(3, Sub)) at (prev + 4, 9) to (start + 0, 14) + = (c1 - (c0 + c2)) +- Code(Counter(3)) at (prev + 2, 14) to (start + 0, 19) +- Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c3 - c0) -- Code(Expression(6, Sub)) at (prev + 1, 22) to (start + 2, 14) +- Code(Expression(8, Sub)) at (prev + 1, 22) to (start + 2, 14) = (c3 - (c0 + c4)) - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25) -- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 14) +- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 14) = (c3 - (c0 + c4)) - Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19) -- Code(Expression(8, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c5 - c0) - Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14) -- Code(Expression(9, Sub)) at (prev + 4, 17) to (start + 0, 25) +- Code(Expression(11, Sub)) at (prev + 4, 17) to (start + 0, 25) = (c5 - (c0 + c6)) - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14) - Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19) -- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 0, 19) +- Code(Expression(13, Sub)) at (prev + 1, 12) to (start + 0, 19) = (c7 - c0) - Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21) -- Code(Expression(12, Sub)) at (prev + 1, 10) to (start + 1, 14) +- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c7 - (c0 + c8)) -- Code(Counter(9)) at (prev + 3, 14) to (start + 0, 19) -- Code(Expression(17, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 14) + = (c7 - (c0 + c8)) +- Code(Counter(9)) at (prev + 2, 14) to (start + 0, 19) +- Code(Expression(21, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c9 - c0) -- Code(Expression(15, Sub)) at (prev + 1, 22) to (start + 2, 14) +- Code(Expression(19, Sub)) at (prev + 1, 22) to (start + 2, 14) = (c9 - (c0 + c10)) - Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14) -- Code(Expression(17, Sub)) at (prev + 4, 9) to (start + 0, 14) +- Code(Expression(21, Sub)) at (prev + 4, 9) to (start + 0, 14) = (c9 - c0) - Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19) - Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22) -- Code(Expression(21, Sub)) at (prev + 1, 22) to (start + 2, 14) +- Code(Expression(25, Sub)) at (prev + 1, 22) to (start + 2, 14) = (c11 - c0) -- Code(Expression(19, Sub)) at (prev + 4, 17) to (start + 0, 22) +- Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 22) = ((c0 + c12) - c11) -- Code(Expression(21, Sub)) at (prev + 3, 9) to (start + 0, 14) +- Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 14) = (c11 - c0) -- Code(Counter(0)) at (prev + 2, 13) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c12 diff --git a/tests/coverage/continue.coverage b/tests/coverage/continue.coverage index 4916cac0038e..17fe4874d151 100644 --- a/tests/coverage/continue.coverage +++ b/tests/coverage/continue.coverage @@ -2,7 +2,7 @@ LL| | LL| 1|fn main() { LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut x = 0; LL| 11| for _ in 0..10 { LL| 10| match is_true { @@ -12,7 +12,7 @@ LL| 0| _ => { LL| 0| x = 1; LL| 0| } - LL| 0| } + LL| | } LL| 0| x = 3; LL| | } LL| 11| for _ in 0..10 { diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map index 0ce915538638..daa42915a4af 100644 --- a/tests/coverage/coroutine.cov-map +++ b/tests/coverage/coroutine.cov-map @@ -1,31 +1,40 @@ Function name: coroutine::get_u32 -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 01, 01, 0b, 05, 02, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 01, 00, 2d, 01, 01, 08, 00, 0b, 05, 01, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/coroutine.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 11) -- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 14) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 45) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 11) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 40) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: coroutine::main -Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02] +Raw bytes (93): 0x[01, 01, 02, 01, 05, 05, 09, 11, 01, 13, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 14, 00, 22, 01, 00, 24, 00, 2a, 01, 00, 2b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/coroutine.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22) -- Code(Counter(0)) at (prev + 8, 11) to (start + 0, 45) +Number of file 0 mappings: 17 +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34) +- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 42) +- Code(Counter(0)) at (prev + 0, 43) to (start + 0, 45) - Code(Counter(1)) at (prev + 1, 43) to (start + 0, 45) - Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20) = (c0 - c1) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46) +- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19) +- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46) +- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34) - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39) - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46) - Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20) @@ -34,12 +43,14 @@ Number of file 0 mappings: 9 Highest counter ID seen: c3 Function name: coroutine::main::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 08, 01, 1f, 05, 02, 10, 01, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 08, 00, 09, 01, 01, 09, 00, 1f, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/coroutine.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 22, 8) to (start + 1, 31) -- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 22, 8) to (start + 0, 9) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 31) +- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c1 diff --git a/tests/coverage/coverage_attr_closure.cov-map b/tests/coverage/coverage_attr_closure.cov-map index e029a3b4643e..deba65f22cca 100644 --- a/tests/coverage/coverage_attr_closure.cov-map +++ b/tests/coverage/coverage_attr_closure.cov-map @@ -1,38 +1,48 @@ Function name: coverage_attr_closure::GLOBAL_CLOSURE_ON::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 0f, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 06, 0f, 00, 10, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 17, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 6, 15) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 6, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: coverage_attr_closure::contains_closures_off::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 13, 02, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 1d, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 29, 19) to (start + 2, 6) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 29, 19) to (start + 0, 20) +- Code(Zero) at (prev + 1, 9) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 0, 27) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) Function name: coverage_attr_closure::contains_closures_on -Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 01, 00, 1a, 01, 01, 09, 00, 1a, 01, 04, 09, 00, 1b, 01, 04, 01, 00, 02] Number of files: 1 - file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26) -- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 27) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 27) - Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 11, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/coverage_attr_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 17, 19) to (start + 2, 6) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 17, 19) to (start + 0, 20) +- Code(Zero) at (prev + 1, 9) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 0, 27) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) diff --git a/tests/coverage/dead_code.cov-map b/tests/coverage/dead_code.cov-map index 4cb311428a18..ae4146dc2467 100644 --- a/tests/coverage/dead_code.cov-map +++ b/tests/coverage/dead_code.cov-map @@ -1,37 +1,52 @@ Function name: dead_code::main -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 1b, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/dead_code.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 15) -- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: dead_code::unused_fn (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] +Raw bytes (49): 0x[01, 01, 00, 09, 00, 0f, 01, 00, 0f, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/dead_code.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Zero) at (prev + 15, 1) to (start + 7, 15) -- Code(Zero) at (prev + 7, 16) to (start + 2, 6) +Number of file 0 mappings: 9 +- Code(Zero) at (prev + 15, 1) to (start + 0, 15) +- Code(Zero) at (prev + 4, 9) to (start + 0, 16) +- Code(Zero) at (prev + 0, 19) to (start + 0, 46) +- Code(Zero) at (prev + 2, 9) to (start + 0, 22) +- Code(Zero) at (prev + 0, 25) to (start + 0, 26) +- Code(Zero) at (prev + 1, 8) to (start + 0, 15) +- Code(Zero) at (prev + 0, 16) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: dead_code::unused_pub_fn_not_in_library (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] +Raw bytes (49): 0x[01, 01, 00, 09, 00, 03, 01, 00, 26, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/dead_code.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Zero) at (prev + 3, 1) to (start + 7, 15) -- Code(Zero) at (prev + 7, 16) to (start + 2, 6) +Number of file 0 mappings: 9 +- Code(Zero) at (prev + 3, 1) to (start + 0, 38) +- Code(Zero) at (prev + 4, 9) to (start + 0, 16) +- Code(Zero) at (prev + 0, 19) to (start + 0, 46) +- Code(Zero) at (prev + 2, 9) to (start + 0, 22) +- Code(Zero) at (prev + 0, 25) to (start + 0, 26) +- Code(Zero) at (prev + 1, 8) to (start + 0, 15) +- Code(Zero) at (prev + 0, 16) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) diff --git a/tests/coverage/dead_code.coverage b/tests/coverage/dead_code.coverage index 55d196f81604..fbb4a001d959 100644 --- a/tests/coverage/dead_code.coverage +++ b/tests/coverage/dead_code.coverage @@ -1,11 +1,11 @@ LL| |#![allow(dead_code, unused_assignments, unused_variables)] LL| | LL| 0|pub fn unused_pub_fn_not_in_library() { - LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 0| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 0| let is_true = std::env::args().len() == 1; - LL| 0| + LL| | LL| 0| let mut countdown = 0; LL| 0| if is_true { LL| 0| countdown = 10; @@ -13,11 +13,11 @@ LL| 0|} LL| | LL| 0|fn unused_fn() { - LL| 0| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 0| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 0| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 0| let is_true = std::env::args().len() == 1; - LL| 0| + LL| | LL| 0| let mut countdown = 0; LL| 0| if is_true { LL| 0| countdown = 10; @@ -25,11 +25,11 @@ LL| 0|} LL| | LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut countdown = 0; LL| 1| if is_true { LL| 1| countdown = 10; diff --git a/tests/coverage/drop_trait.cov-map b/tests/coverage/drop_trait.cov-map index a52ebd87aa82..dcf9dbd8c647 100644 --- a/tests/coverage/drop_trait.cov-map +++ b/tests/coverage/drop_trait.cov-map @@ -1,21 +1,33 @@ Function name: ::drop -Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 05, 02, 06] -Number of files: 1 -- file 0 => $DIR/drop_trait.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 9, 5) to (start + 2, 6) -Highest counter ID seen: c0 - -Function name: drop_trait::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 01, 05, 0c, 01, 06, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/drop_trait.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 14, 1) to (start + 5, 12) -- Code(Counter(0)) at (prev + 6, 9) to (start + 1, 22) -- Code(Zero) at (prev + 2, 6) to (start + 4, 11) -- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2) +- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + +Function name: drop_trait::main +Raw bytes (69): 0x[01, 01, 00, 0d, 01, 0e, 01, 00, 1c, 01, 01, 09, 00, 15, 01, 00, 18, 00, 30, 01, 02, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/drop_trait.rs +Number of expressions: 0 +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 48) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) +- Code(Zero) at (prev + 2, 13) to (start + 0, 40) +- Code(Zero) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/drop_trait.coverage b/tests/coverage/drop_trait.coverage index 85d557573cf3..10ed8c0f154f 100644 --- a/tests/coverage/drop_trait.coverage +++ b/tests/coverage/drop_trait.coverage @@ -13,16 +13,16 @@ LL| | LL| 1|fn main() -> Result<(), u8> { LL| 1| let _firecracker = Firework { strength: 1 }; - LL| 1| + LL| | LL| 1| let _tnt = Firework { strength: 100 }; - LL| 1| + LL| | LL| 1| if true { LL| 1| println!("Exiting with error..."); LL| 1| return Err(1); LL| 0| } - LL| 0| + LL| | LL| 0| let _ = Firework { strength: 1000 }; - LL| 0| + LL| | LL| 0| Ok(()) LL| 1|} LL| | diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map index 465baa7f7f9b..fc57a4892be4 100644 --- a/tests/coverage/fn_sig_into_try.cov-map +++ b/tests/coverage/fn_sig_into_try.cov-map @@ -1,44 +1,52 @@ Function name: fn_sig_into_try::a -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 05, 02] -Number of files: 1 -- file 0 => $DIR/fn_sig_into_try.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 1) to (start + 5, 2) -Highest counter ID seen: c0 - -Function name: fn_sig_into_try::b -Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 0a, 01, 00, 16, 01, 03, 05, 00, 0f, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15) -- Code(Zero) at (prev + 3, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 + +Function name: fn_sig_into_try::b +Raw bytes (29): 0x[01, 01, 00, 05, 01, 11, 01, 00, 16, 01, 03, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/fn_sig_into_try.rs +Number of expressions: 0 +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 15) to (start + 0, 16) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: fn_sig_into_try::c -Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 18, 01, 00, 16, 01, 03, 0d, 00, 17, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23) -- Code(Zero) at (prev + 3, 23) to (start + 0, 24) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 3, 13) to (start + 0, 23) +- Code(Zero) at (prev + 0, 23) to (start + 0, 24) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: fn_sig_into_try::d -Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (39): 0x[01, 01, 00, 07, 01, 1f, 01, 00, 16, 01, 03, 0c, 00, 0e, 01, 00, 11, 00, 13, 01, 01, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/fn_sig_into_try.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15) -- Code(Zero) at (prev + 4, 15) to (start + 0, 16) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 3, 12) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 15) to (start + 0, 16) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/fn_sig_into_try.coverage b/tests/coverage/fn_sig_into_try.coverage index cabe747ce5ac..bc744db4b69c 100644 --- a/tests/coverage/fn_sig_into_try.coverage +++ b/tests/coverage/fn_sig_into_try.coverage @@ -8,31 +8,31 @@ LL| |// signature should be handled in the same way. LL| | LL| 1|fn a() -> Option - LL| 1|// - LL| 1|{ + LL| |// + LL| |{ LL| 1| Some(7i32); LL| 1| Some(0) LL| 1|} LL| | LL| 1|fn b() -> Option - LL| 1|// - LL| 1|{ + LL| |// + LL| |{ LL| 1| Some(7i32)?; ^0 LL| 1| Some(0) LL| 1|} LL| | LL| 1|fn c() -> Option - LL| 1|// - LL| 1|{ + LL| |// + LL| |{ LL| 1| let _ = Some(7i32)?; ^0 LL| 1| Some(0) LL| 1|} LL| | LL| 1|fn d() -> Option - LL| 1|// - LL| 1|{ + LL| |// + LL| |{ LL| 1| let _: () = (); LL| 1| Some(7i32)?; ^0 diff --git a/tests/coverage/generic-unused-impl.cov-map b/tests/coverage/generic-unused-impl.cov-map index 119c426965d1..da9e5495a72b 100644 --- a/tests/coverage/generic-unused-impl.cov-map +++ b/tests/coverage/generic-unused-impl.cov-map @@ -1,18 +1,23 @@ Function name: as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 03, 06] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 0b, 05, 00, 29, 00, 01, 0e, 00, 12, 00, 00, 16, 00, 1a, 00, 01, 09, 00, 1b, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/generic-unused-impl.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 11, 5) to (start + 3, 6) +Number of file 0 mappings: 5 +- Code(Zero) at (prev + 11, 5) to (start + 0, 41) +- Code(Zero) at (prev + 1, 14) to (start + 0, 18) +- Code(Zero) at (prev + 0, 22) to (start + 0, 26) +- Code(Zero) at (prev + 1, 9) to (start + 0, 27) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: (none) Function name: generic_unused_impl::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 0d] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d] Number of files: 1 - file 0 => $DIR/generic-unused-impl.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 13) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) Highest counter ID seen: c0 diff --git a/tests/coverage/generics.cov-map b/tests/coverage/generics.cov-map index 92c6ad01e300..7f9b7ee0f471 100644 --- a/tests/coverage/generics.cov-map +++ b/tests/coverage/generics.cov-map @@ -1,48 +1,73 @@ Function name: as core::ops::drop::Drop>::drop -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] -Number of files: 1 -- file 0 => $DIR/generics.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) -Highest counter ID seen: c0 - -Function name: >::set_strength -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06] -Number of files: 1 -- file 0 => $DIR/generics.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6) -Highest counter ID seen: c0 - -Function name: as core::ops::drop::Drop>::drop -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06] -Number of files: 1 -- file 0 => $DIR/generics.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6) -Highest counter ID seen: c0 - -Function name: >::set_strength -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06] -Number of files: 1 -- file 0 => $DIR/generics.rs -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6) -Highest counter ID seen: c0 - -Function name: generics::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 08, 0c, 01, 09, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/generics.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 22, 1) to (start + 8, 12) -- Code(Counter(0)) at (prev + 9, 9) to (start + 1, 22) -- Code(Zero) at (prev + 2, 6) to (start + 4, 11) -- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2) +- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + +Function name: >::set_strength +Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/generics.rs +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + +Function name: as core::ops::drop::Drop>::drop +Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/generics.rs +Number of expressions: 0 +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + +Function name: >::set_strength +Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/generics.rs +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + +Function name: generics::main +Raw bytes (99): 0x[01, 01, 00, 13, 01, 16, 01, 00, 1c, 01, 01, 09, 00, 18, 01, 00, 1b, 00, 33, 01, 01, 05, 00, 10, 01, 00, 11, 00, 1d, 01, 02, 09, 00, 10, 01, 00, 13, 00, 2f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => $DIR/generics.rs +Number of expressions: 0 +Number of file 0 mappings: 19 +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 24) +- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 51) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 29) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 47) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21) +- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) +- Code(Zero) at (prev + 2, 13) to (start + 0, 40) +- Code(Zero) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/generics.coverage b/tests/coverage/generics.coverage index a2cd1465d26f..43697cacb9a5 100644 --- a/tests/coverage/generics.coverage +++ b/tests/coverage/generics.coverage @@ -44,18 +44,18 @@ LL| 1|fn main() -> Result<(), u8> { LL| 1| let mut firecracker = Firework { strength: 1 }; LL| 1| firecracker.set_strength(2); - LL| 1| + LL| | LL| 1| let mut tnt = Firework { strength: 100.1 }; LL| 1| tnt.set_strength(200.1); LL| 1| tnt.set_strength(300.3); - LL| 1| + LL| | LL| 1| if true { LL| 1| println!("Exiting with error..."); LL| 1| return Err(1); LL| 0| } - LL| 0| + LL| | LL| 0| let _ = Firework { strength: 1000 }; - LL| 0| + LL| | LL| 0| Ok(()) LL| 1|} LL| | diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map index 5298c2d92d5d..c2158c441506 100644 --- a/tests/coverage/holes.cov-map +++ b/tests/coverage/holes.cov-map @@ -1,57 +1,81 @@ Function name: ::_method (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 2b, 09, 00, 1a, 00, 00, 1c, 00, 1d] Number of files: 1 - file 0 => $DIR/holes.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 43, 9) to (start + 0, 29) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 43, 9) to (start + 0, 26) +- Code(Zero) at (prev + 0, 28) to (start + 0, 29) Highest counter ID seen: (none) Function name: holes::main -Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 11, 01, 05, 05, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 11, 01, 04, 05, 00, 11, 01, 07, 05, 00, 11, 01, 06, 05, 00, 11, 01, 04, 05, 00, 11, 01, 04, 05, 00, 11, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 06, 27, 01, 13, 05, 01, 02] +Raw bytes (154): 0x[01, 01, 00, 1e, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 09, 00, 27, 01, 0d, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/holes.rs Number of expressions: 0 -Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 17) -- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 17) +Number of file 0 mappings: 30 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) - Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17) -- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17) -- Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15) -- Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15) -- Code(Counter(0)) at (prev + 10, 5) to (start + 6, 39) -- Code(Counter(0)) at (prev + 19, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 6, 9) to (start + 0, 39) +- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: holes::main::_unused_fn (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 1f, 05, 00, 14, 00, 00, 16, 00, 17] Number of files: 1 - file 0 => $DIR/holes.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 31, 5) to (start + 0, 23) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 31, 5) to (start + 0, 20) +- Code(Zero) at (prev + 0, 22) to (start + 0, 23) Highest counter ID seen: (none) Function name: holes::main::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 18, 09, 00, 0a, 00, 01, 0d, 00, 16, 00, 00, 17, 00, 19, 00, 01, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/holes.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 24, 9) to (start + 2, 10) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 24, 9) to (start + 0, 10) +- Code(Zero) at (prev + 1, 13) to (start + 0, 22) +- Code(Zero) at (prev + 0, 23) to (start + 0, 25) +- Code(Zero) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: (none) Function name: holes::main::{closure#1} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 4b, 09, 00, 0a, 00, 01, 0d, 00, 12, 00, 01, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/holes.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 75, 9) to (start + 2, 10) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 75, 9) to (start + 0, 10) +- Code(Zero) at (prev + 1, 13) to (start + 0, 18) +- Code(Zero) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: (none) diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage index a6a02f1b9d08..1ea60491800d 100644 --- a/tests/coverage/holes.coverage +++ b/tests/coverage/holes.coverage @@ -58,8 +58,8 @@ LL| | } LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| #[rustfmt::skip] + LL| | + LL| | #[rustfmt::skip] LL| 1| let _const = LL| | const LL| | { @@ -68,8 +68,8 @@ LL| | ; LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| #[rustfmt::skip] + LL| | + LL| | #[rustfmt::skip] LL| 1| let _async = LL| | async LL| 0| { @@ -78,11 +78,11 @@ LL| | ; LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| // This tests the edge case of a const block nested inside an "anon const", - LL| 1| // such as the length of an array literal. Handling this case requires - LL| 1| // `nested_filter::OnlyBodies` or equivalent. - LL| 1| #[rustfmt::skip] + LL| | + LL| | // This tests the edge case of a const block nested inside an "anon const", + LL| | // such as the length of an array literal. Handling this case requires + LL| | // `nested_filter::OnlyBodies` or equivalent. + LL| | #[rustfmt::skip] LL| 1| let _const_block_inside_anon_const = LL| | [ LL| | 0 diff --git a/tests/coverage/if.cov-map b/tests/coverage/if.cov-map index 611dd2ef08d5..044c0f2ba089 100644 --- a/tests/coverage/if.cov-map +++ b/tests/coverage/if.cov-map @@ -1,12 +1,17 @@ Function name: if::main -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 04, 01, 12, 10, 05, 13, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 04, 01, 00, 0a, 01, 05, 05, 00, 0c, 01, 02, 09, 02, 0a, 01, 05, 09, 01, 0e, 01, 03, 09, 00, 0a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 4, 1) to (start + 18, 16) -- Code(Counter(1)) at (prev + 19, 5) to (start + 5, 6) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 12) +- Code(Counter(0)) at (prev + 2, 9) to (start + 2, 10) +- Code(Counter(0)) at (prev + 5, 9) to (start + 1, 14) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6) - Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) diff --git a/tests/coverage/if.coverage b/tests/coverage/if.coverage index 0762418347c2..c3c8a1bf38a4 100644 --- a/tests/coverage/if.coverage +++ b/tests/coverage/if.coverage @@ -2,23 +2,23 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. - LL| 1| let + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. + LL| | let LL| 1| is_true - LL| 1| = + LL| | = LL| 1| std::env::args().len() LL| 1| == LL| 1| 1 - LL| 1| ; - LL| 1| let + LL| | ; + LL| | let LL| 1| mut LL| 1| countdown - LL| 1| = + LL| | = LL| 1| 0 - LL| 1| ; - LL| 1| if + LL| | ; + LL| | if LL| 1| is_true LL| 1| { LL| 1| countdown diff --git a/tests/coverage/if_else.cov-map b/tests/coverage/if_else.cov-map index 35096d859502..1d8ca1809532 100644 --- a/tests/coverage/if_else.cov-map +++ b/tests/coverage/if_else.cov-map @@ -1,13 +1,18 @@ Function name: if_else::main -Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 08, 10, 05, 09, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02] +Raw bytes (68): 0x[01, 01, 02, 01, 05, 01, 09, 0c, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 02, 09, 00, 10, 05, 01, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if_else.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 4, 1) to (start + 8, 16) -- Code(Counter(1)) at (prev + 9, 5) to (start + 5, 6) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6) - Code(Expression(0, Sub)) at (prev + 8, 9) to (start + 2, 16) = (c0 - c1) - Code(Counter(0)) at (prev + 6, 9) to (start + 0, 16) diff --git a/tests/coverage/if_else.coverage b/tests/coverage/if_else.coverage index 2bf93487cec2..148e2b195173 100644 --- a/tests/coverage/if_else.coverage +++ b/tests/coverage/if_else.coverage @@ -2,13 +2,13 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut countdown = 0; - LL| 1| if + LL| | if LL| 1| is_true LL| 1| { LL| 1| countdown diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map index 0fd35c55e3e5..1b1a1b30e934 100644 --- a/tests/coverage/if_not.cov-map +++ b/tests/coverage/if_not.cov-map @@ -1,14 +1,15 @@ Function name: if_not::if_not -Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0b, 01, 05, 01, 00, 16, 01, 02, 09, 01, 0d, 02, 02, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if_not.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 13) -- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 2, 6) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 2, 9) to (start + 1, 13) +- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 2, 6) = (c0 - c1) - Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 13) diff --git a/tests/coverage/if_not.coverage b/tests/coverage/if_not.coverage index 678ccf9f2f85..8478e861a3aa 100644 --- a/tests/coverage/if_not.coverage +++ b/tests/coverage/if_not.coverage @@ -3,7 +3,7 @@ LL| | LL| |#[rustfmt::skip] LL| 12|fn if_not(cond: bool) { - LL| 12| if + LL| | if LL| 12| ! LL| 12| cond LL| 4| { diff --git a/tests/coverage/ignore_run.cov-map b/tests/coverage/ignore_run.cov-map index a93fff71530b..0d8245c54dc4 100644 --- a/tests/coverage/ignore_run.cov-map +++ b/tests/coverage/ignore_run.cov-map @@ -1,9 +1,10 @@ Function name: ignore_run::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d] Number of files: 1 - file 0 => $DIR/ignore_run.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) Highest counter ID seen: c0 diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map index 450fb75b7c8e..95a5f6bf68b7 100644 --- a/tests/coverage/inline-dead.cov-map +++ b/tests/coverage/inline-dead.cov-map @@ -1,44 +1,53 @@ Function name: inline_dead::dead (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 17, 01, 00, 11, 00, 01, 05, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline-dead.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 23, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 23, 1) to (start + 0, 17) +- Code(Zero) at (prev + 1, 5) to (start + 0, 7) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: inline_dead::live:: -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0e, 01, 00, 20, 01, 01, 08, 00, 09, 05, 01, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline-dead.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9) -- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 13) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 13) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: inline_dead::main -Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02] +Raw bytes (39): 0x[01, 01, 00, 07, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 00, 14, 00, 21, 01, 02, 09, 00, 0a, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline-dead.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10) -- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 2) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 33) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: inline_dead::main::{closure#0} -Raw bytes (19): 0x[01, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 01, 01, 05, 00, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 17, 00, 18, 01, 01, 09, 00, 16, 00, 00, 17, 00, 18, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/inline-dead.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22) -- Code(Zero) at (prev + 1, 23) to (start + 0, 24) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 7, 23) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Zero) at (prev + 0, 23) to (start + 0, 24) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c0 diff --git a/tests/coverage/inline-dead.coverage b/tests/coverage/inline-dead.coverage index c12668ce89a2..d75aaf300623 100644 --- a/tests/coverage/inline-dead.coverage +++ b/tests/coverage/inline-dead.coverage @@ -3,7 +3,7 @@ LL| | LL| 1|fn main() { LL| 1| println!("{}", live::()); - LL| 1| + LL| | LL| 1| let f = |x: bool| { LL| 1| debug_assert!(x); ^0 diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map index 5aa57e15bd5c..4c67dd96ac2f 100644 --- a/tests/coverage/inline.cov-map +++ b/tests/coverage/inline.cov-map @@ -1,86 +1,137 @@ Function name: inline::display:: -Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 29, 01, 00, 22, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 01, 02] +Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 34) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6) = (c1 - c0) -- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: inline::error -Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 0b] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 01, 00, 0b, 01, 01, 05, 00, 0b] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 11) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) Highest counter ID seen: c0 Function name: inline::length:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 1e, 01, 00, 20, 01, 01, 05, 00, 07, 01, 00, 08, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7) +- Code(Counter(0)) at (prev + 0, 8) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: inline::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 05, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 00, 12, 00, 22, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: inline::permutate:: -Raw bytes (54): 0x[01, 01, 05, 01, 05, 0d, 09, 0d, 09, 01, 13, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 0a, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 0a, 00, 17, 04, 0a, 0e, 05, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (142): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 16, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 13, 09, 00, 15, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs -Number of expressions: 5 +Number of expressions: 14 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(3), rhs = Counter(2) - expression 2 operands: lhs = Counter(3), rhs = Counter(2) -- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) -- expression 4 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14) -- Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6) +- expression 3 operands: lhs = Counter(3), rhs = Counter(2) +- expression 4 operands: lhs = Counter(3), rhs = Counter(2) +- expression 5 operands: lhs = Counter(3), rhs = Counter(2) +- expression 6 operands: lhs = Counter(3), rhs = Counter(2) +- expression 7 operands: lhs = Counter(3), rhs = Counter(2) +- expression 8 operands: lhs = Counter(3), rhs = Counter(2) +- expression 9 operands: lhs = Counter(3), rhs = Counter(2) +- expression 10 operands: lhs = Counter(3), rhs = Counter(2) +- expression 11 operands: lhs = Counter(3), rhs = Counter(2) +- expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add) +- expression 13 operands: lhs = Counter(1), rhs = Counter(2) +Number of file 0 mappings: 22 +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 56) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14) +- Code(Counter(1)) at (prev + 0, 15) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 15) to (start + 0, 20) = (c0 - c1) -- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 0, 14) +- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 14) = (c3 - c2) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22) -- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 4, 10) +- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19) +- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 22) +- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 4, 10) = (c3 - c2) -- Code(Expression(3, Sub)) at (prev + 5, 12) to (start + 2, 6) +- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 22) to (start + 0, 23) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 25) to (start + 0, 26) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 22) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 0, 25) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 27) to (start + 0, 32) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17) + = (c3 - c2) +- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20) + = (c3 - c2) +- Code(Expression(12, Sub)) at (prev + 2, 12) to (start + 2, 6) = (c0 - (c1 + c2)) - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: inline::permutations:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 03, 02] +Raw bytes (39): 0x[01, 01, 00, 07, 01, 0a, 01, 00, 2d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 14, 01, 00, 15, 00, 1d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 16, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 1) to (start + 3, 2) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 45) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 20) +- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: inline::swap:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 04, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 23, 01, 00, 33, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 0e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 35, 1) to (start + 4, 2) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 51) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/inline.coverage b/tests/coverage/inline.coverage index 3d322126a38b..5fe069d5389d 100644 --- a/tests/coverage/inline.coverage +++ b/tests/coverage/inline.coverage @@ -18,7 +18,7 @@ LL| 6| display(xs); LL| 10| } else if k < n { LL| 15| for i in k..n { - ^10 + ^10^10 LL| 15| swap(xs, i, k); LL| 15| permutate(xs, k + 1); LL| 15| swap(xs, i, k); diff --git a/tests/coverage/inner_items.cov-map b/tests/coverage/inner_items.cov-map index a9e19fe53a53..ca6ddfda2ddf 100644 --- a/tests/coverage/inner_items.cov-map +++ b/tests/coverage/inner_items.cov-map @@ -1,46 +1,70 @@ Function name: ::default_trait_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 09, 03, 0a] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 21, 09, 00, 29, 01, 01, 0d, 00, 14, 01, 01, 0d, 00, 11, 01, 00, 12, 00, 1c, 01, 01, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/inner_items.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 9) to (start + 3, 10) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 33, 9) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: c0 Function name: ::trait_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 09, 03, 0a] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 28, 09, 00, 2c, 01, 01, 0d, 00, 29, 01, 01, 0d, 00, 14, 01, 00, 15, 00, 29, 01, 01, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/inner_items.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 40, 9) to (start + 3, 10) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 40, 9) to (start + 0, 44) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20) +- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: c0 Function name: inner_items::main -Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 05, 02] +Raw bytes (88): 0x[01, 01, 02, 01, 05, 01, 09, 10, 01, 03, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 00, 10, 01, 00, 13, 02, 06, 01, 04, 05, 00, 08, 01, 00, 09, 00, 1b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inner_items.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15) -- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6) +Number of file 0 mappings: 16 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 36, 8) to (start + 0, 15) - Code(Counter(2)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c2) -- Code(Counter(0)) at (prev + 2, 9) to (start + 5, 2) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 2, 6) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 8) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 27) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: inner_items::main::in_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 05, 04, 06] +Raw bytes (44): 0x[01, 01, 00, 08, 01, 12, 05, 00, 17, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 16, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/inner_items.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 18, 5) to (start + 4, 6) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 18, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c0 diff --git a/tests/coverage/inner_items.coverage b/tests/coverage/inner_items.coverage index 8244d347b59c..8503cc12f233 100644 --- a/tests/coverage/inner_items.coverage +++ b/tests/coverage/inner_items.coverage @@ -1,11 +1,11 @@ LL| |#![allow(unused_assignments, unused_variables, dead_code)] LL| | LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut countdown = 0; LL| 1| if is_true { LL| 1| countdown = 10; @@ -54,7 +54,7 @@ LL| 1| let mut val = InStruct { LL| 1| in_struct_field: 101, // LL| 1| }; - LL| 1| + LL| | LL| 1| val.default_trait_func(); LL| 1|} diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index 4e45db836d67..d1d751ff24b8 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,13 +1,30 @@ Function name: issue_83601::main -Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02] +Raw bytes (76): 0x[01, 01, 01, 05, 09, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-83601.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 15) -- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) + = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2) = (c1 - c2) Highest counter ID seen: c1 diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 1ed5edbb8191..2b643ea599ed 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -1,65 +1,79 @@ Function name: ::fmt -Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 24, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, 8a, 01, 05, 00, 43, 01, 01, 09, 00, 0f, 01, 00, 10, 00, 11, 01, 00, 13, 00, 24, 05, 00, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 138, 5) to (start + 1, 36) -- Code(Counter(1)) at (prev + 1, 37) to (start + 0, 38) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 138, 5) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 36) +- Code(Counter(1)) at (prev + 0, 37) to (start + 0, 38) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: issue_84561::main -Raw bytes (10): 0x[01, 01, 00, 01, 01, b4, 01, 01, 04, 02] +Raw bytes (30): 0x[01, 01, 00, 05, 01, b4, 01, 01, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 180, 1) to (start + 4, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 180, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: issue_84561::test1 -Raw bytes (50): 0x[01, 01, 00, 09, 01, 9a, 01, 01, 01, 0b, 05, 01, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 01, 0b, 0d, 01, 0c, 00, 1e, 01, 01, 05, 03, 0b, 11, 03, 0c, 00, 1e, 01, 01, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 00, 0c, 01, 9a, 01, 01, 00, 0b, 01, 01, 05, 00, 0b, 05, 00, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 05, 00, 0b, 0d, 00, 0c, 00, 1e, 01, 01, 05, 02, 06, 01, 03, 05, 00, 0b, 11, 00, 0c, 00, 1e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 0 -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 154, 1) to (start + 1, 11) -- Code(Counter(1)) at (prev + 1, 12) to (start + 0, 30) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 154, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) +- Code(Counter(1)) at (prev + 0, 12) to (start + 0, 30) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) - Code(Counter(2)) at (prev + 0, 12) to (start + 0, 30) -- Code(Counter(0)) at (prev + 1, 13) to (start + 1, 11) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 30) -- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 11) -- Code(Counter(4)) at (prev + 3, 12) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) +- Code(Counter(3)) at (prev + 0, 12) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 5) to (start + 2, 6) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 11) +- Code(Counter(4)) at (prev + 0, 12) to (start + 0, 30) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c4 Function name: issue_84561::test2 -Raw bytes (20): 0x[01, 01, 00, 03, 01, b0, 01, 01, 01, 10, 05, 01, 11, 00, 23, 01, 01, 01, 00, 02] +Raw bytes (25): 0x[01, 01, 00, 04, 01, b0, 01, 01, 00, 0b, 01, 01, 05, 00, 10, 05, 00, 11, 00, 23, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 176, 1) to (start + 1, 16) -- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 35) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 176, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16) +- Code(Counter(1)) at (prev + 0, 17) to (start + 0, 35) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: issue_84561::test2::call_print -Raw bytes (10): 0x[01, 01, 00, 01, 01, a7, 01, 09, 02, 0a] +Raw bytes (25): 0x[01, 01, 00, 04, 01, a7, 01, 09, 00, 1f, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 18, 01, 01, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 167, 9) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (409): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 02, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 00, 0c, 09, 00, 0f, 00, 15, 09, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 00, 10, 0d, 00, 13, 00, 2e, 0d, 02, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 00, 0c, 0d, 00, 0f, 00, 15, 0d, 01, 05, 00, 0f, 0d, 04, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 00, 0f, 1d, 02, 0c, 00, 13, 21, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 10 @@ -73,29 +87,54 @@ Number of expressions: 10 - expression 7 operands: lhs = Counter(9), rhs = Counter(10) - expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12) - expression 9 operands: lhs = Counter(10), rhs = Counter(11) -Number of file 0 mappings: 51 -- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 15) -- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 15) -- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 15) -- Code(Counter(2)) at (prev + 5, 5) to (start + 0, 15) +Number of file 0 mappings: 77 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 15) - Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 48) -- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 15) -- Code(Zero) at (prev + 3, 32) to (start + 0, 48) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) +- Code(Zero) at (prev + 0, 32) to (start + 0, 36) +- Code(Zero) at (prev + 0, 41) to (start + 0, 48) - Code(Zero) at (prev + 0, 51) to (start + 0, 65) - Code(Zero) at (prev + 0, 75) to (start + 0, 90) - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Zero) at (prev + 5, 9) to (start + 3, 16) -- Code(Zero) at (prev + 5, 13) to (start + 0, 27) +- Code(Zero) at (prev + 5, 9) to (start + 0, 13) +- Code(Zero) at (prev + 3, 9) to (start + 0, 16) +- Code(Zero) at (prev + 2, 13) to (start + 0, 27) - Code(Zero) at (prev + 2, 13) to (start + 0, 28) -- Code(Counter(3)) at (prev + 4, 9) to (start + 2, 15) -- Code(Counter(3)) at (prev + 6, 5) to (start + 0, 15) +- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(3)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) - Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 9) to (start + 1, 15) -- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15) +- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 12) +- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(3)) at (prev + 4, 8) to (start + 0, 15) - Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19) = (c3 - c4) @@ -110,8 +149,9 @@ Number of file 0 mappings: 51 - Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19) = (c3 - c6) -- Code(Counter(7)) at (prev + 4, 5) to (start + 2, 19) -- Code(Counter(8)) at (prev + 3, 13) to (start + 0, 19) +- Code(Counter(7)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 19) +- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19) = (c7 - c8) - Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15) diff --git a/tests/coverage/issue-84561.coverage b/tests/coverage/issue-84561.coverage index a55f42a696e6..781f1e97f5ab 100644 --- a/tests/coverage/issue-84561.coverage +++ b/tests/coverage/issue-84561.coverage @@ -14,7 +14,7 @@ LL| 1| println!("{:?}", Foo(1)); LL| 1| println!("{:?}", bar); LL| 1| println!("{:?}", baz); - LL| 1| + LL| | LL| 1| assert_eq!(Foo(1), Foo(1)); LL| 1| assert_ne!(Foo(0), Foo(1)); LL| 1| assert_eq!(Foo(2), Foo(2)); @@ -25,17 +25,17 @@ ^0 LL| 1| println!("{:?}", bar); LL| 1| println!("{:?}", Foo(1)); - LL| 1| + LL| | LL| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" }); - ^0 ^0 ^0 + ^0 ^0 ^0 ^0 LL| 1| assert_ne!( LL| | Foo(0) LL| | , LL| | Foo(5) LL| | , LL| 0| "{}" - LL| 0| , - LL| 0| if + LL| | , + LL| | if LL| 0| is_true LL| | { LL| 0| "true message" @@ -45,7 +45,7 @@ LL| | ); LL| | LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| assert_eq!( LL| | Foo(1), LL| | Foo(1) @@ -96,7 +96,7 @@ LL| | Foo(5) LL| | ); LL| 1| assert_ne!( - LL| 1| Foo(5), + LL| | Foo(5), LL| 1| if is_true { LL| 1| Foo(0) LL| | } else { diff --git a/tests/coverage/issue-85461.cov-map b/tests/coverage/issue-85461.cov-map index 566206a7539d..b08d70336930 100644 --- a/tests/coverage/issue-85461.cov-map +++ b/tests/coverage/issue-85461.cov-map @@ -1,9 +1,12 @@ Function name: issue_85461::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-85461.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/issue-93054.cov-map b/tests/coverage/issue-93054.cov-map index 3cb54d80e7f0..17f3dafce1d7 100644 --- a/tests/coverage/issue-93054.cov-map +++ b/tests/coverage/issue-93054.cov-map @@ -1,27 +1,30 @@ Function name: issue_93054::foo2 (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1c] Number of files: 1 - file 0 => $DIR/issue-93054.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 1) to (start + 0, 29) +- Code(Zero) at (prev + 21, 1) to (start + 0, 28) Highest counter ID seen: (none) Function name: issue_93054::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 0d] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 1d, 01, 00, 0a, 01, 00, 0c, 00, 0d] Number of files: 1 - file 0 => $DIR/issue-93054.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 13) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) Highest counter ID seen: c0 Function name: issue_93054::make (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 01, 00, 1b, 00, 01, 05, 00, 09, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-93054.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 25, 1) to (start + 0, 27) +- Code(Zero) at (prev + 1, 5) to (start + 0, 9) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map index 9722b4c2a325..cbbe6a89fb0f 100644 --- a/tests/coverage/lazy_boolean.cov-map +++ b/tests/coverage/lazy_boolean.cov-map @@ -1,5 +1,5 @@ Function name: lazy_boolean::main -Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (198): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 24, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 0a, 00, 0f, 01, 00, 11, 00, 16, 01, 00, 18, 00, 1d, 01, 00, 21, 00, 2a, 01, 01, 08, 00, 0f, 05, 00, 10, 04, 06, 05, 01, 09, 00, 0e, 02, 03, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/lazy_boolean.rs Number of expressions: 7 @@ -10,10 +10,18 @@ Number of expressions: 7 - expression 4 operands: lhs = Counter(0), rhs = Counter(5) - expression 5 operands: lhs = Counter(0), rhs = Counter(6) - expression 6 operands: lhs = Counter(0), rhs = Counter(7) -Number of file 0 mappings: 28 -- Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15) -- Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6) -- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6) +Number of file 0 mappings: 36 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 10) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 29) +- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 42) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 4, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 17) - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18) diff --git a/tests/coverage/lazy_boolean.coverage b/tests/coverage/lazy_boolean.coverage index 828ba2a58116..0a30038e02fa 100644 --- a/tests/coverage/lazy_boolean.coverage +++ b/tests/coverage/lazy_boolean.coverage @@ -2,11 +2,11 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let (mut a, mut b, mut c) = (0, 0, 0); LL| 1| if is_true { LL| 1| a = 1; diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map index f55e5a930b47..169d4a5c0961 100644 --- a/tests/coverage/let_else_loop.cov-map +++ b/tests/coverage/let_else_loop.cov-map @@ -1,33 +1,36 @@ Function name: let_else_loop::_if (unused) -Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 16, 01, 00, 13, 00, 01, 08, 00, 0c, 00, 00, 0f, 00, 16, 00, 00, 20, 00, 27] Number of files: 1 - file 0 => $DIR/let_else_loop.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Zero) at (prev + 22, 1) to (start + 1, 12) -- Code(Zero) at (prev + 1, 15) to (start + 0, 22) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 22, 1) to (start + 0, 19) +- Code(Zero) at (prev + 1, 8) to (start + 0, 12) +- Code(Zero) at (prev + 0, 15) to (start + 0, 22) - Code(Zero) at (prev + 0, 32) to (start + 0, 39) Highest counter ID seen: (none) Function name: let_else_loop::_loop_either_way (unused) -Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 00, 20, 00, 01, 10, 00, 14, 00, 00, 1c, 00, 23, 00, 01, 05, 00, 0c] Number of files: 1 - file 0 => $DIR/let_else_loop.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Zero) at (prev + 15, 1) to (start + 1, 20) -- Code(Zero) at (prev + 1, 28) to (start + 0, 35) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 15, 1) to (start + 0, 32) +- Code(Zero) at (prev + 1, 16) to (start + 0, 20) +- Code(Zero) at (prev + 0, 28) to (start + 0, 35) - Code(Zero) at (prev + 1, 5) to (start + 0, 12) Highest counter ID seen: (none) Function name: let_else_loop::loopy -Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 01, 00, 15, 01, 01, 10, 00, 14, 09, 00, 1c, 00, 23, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/let_else_loop.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20) -- Code(Counter(2)) at (prev + 1, 28) to (start + 0, 35) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 20) +- Code(Counter(2)) at (prev + 0, 28) to (start + 0, 35) - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 diff --git a/tests/coverage/long_and_wide.cov-map b/tests/coverage/long_and_wide.cov-map index c8194ccc79b3..93466a98eaf3 100644 --- a/tests/coverage/long_and_wide.cov-map +++ b/tests/coverage/long_and_wide.cov-map @@ -1,36 +1,44 @@ Function name: long_and_wide::far_function -Raw bytes (10): 0x[01, 01, 00, 01, 01, 96, 01, 01, 00, 15] +Raw bytes (15): 0x[01, 01, 00, 02, 01, 96, 01, 01, 00, 12, 01, 00, 14, 00, 15] Number of files: 1 - file 0 => $DIR/long_and_wide.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 21) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) Highest counter ID seen: c0 Function name: long_and_wide::long_function -Raw bytes (10): 0x[01, 01, 00, 01, 01, 10, 01, 84, 01, 02] +Raw bytes (15): 0x[01, 01, 00, 02, 01, 10, 01, 00, 13, 01, 84, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/long_and_wide.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 16, 1) to (start + 132, 2) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 132, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: long_and_wide::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 04, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 07, 01, 00, 0a, 01, 01, 05, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/long_and_wide.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 1) to (start + 4, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: long_and_wide::wide_function -Raw bytes (10): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 8b, 01] +Raw bytes (23): 0x[01, 01, 00, 03, 01, 0e, 01, 00, 13, 01, 00, 86, 01, 00, 88, 01, 01, 00, 8a, 01, 00, 8b, 01] Number of files: 1 - file 0 => $DIR/long_and_wide.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 139) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 134) to (start + 0, 136) +- Code(Counter(0)) at (prev + 0, 138) to (start + 0, 139) Highest counter ID seen: c0 diff --git a/tests/coverage/long_and_wide.coverage b/tests/coverage/long_and_wide.coverage index f0898d9f4662..d9bacdf9eed3 100644 --- a/tests/coverage/long_and_wide.coverage +++ b/tests/coverage/long_and_wide.coverage @@ -14,137 +14,137 @@ LL| 1|fn wide_function() { /* */ (); } LL| | LL| 1|fn long_function() { - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // - LL| 1| // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // + LL| | // LL| 1|} LL| | LL| 1|fn far_function() {} diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map index 8edb6d06dd6d..3981623550dd 100644 --- a/tests/coverage/loop-break.cov-map +++ b/tests/coverage/loop-break.cov-map @@ -1,11 +1,11 @@ Function name: loop_break::main -Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0a, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/loop-break.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) - Code(Counter(1)) at (prev + 2, 12) to (start + 0, 33) - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) diff --git a/tests/coverage/loop_break_value.cov-map b/tests/coverage/loop_break_value.cov-map index d16335a0a291..cf355eceb2c1 100644 --- a/tests/coverage/loop_break_value.cov-map +++ b/tests/coverage/loop_break_value.cov-map @@ -1,9 +1,12 @@ Function name: loop_break_value::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 0a, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 02, 0d, 05, 0a, 01, 07, 01, 00, 02] Number of files: 1 - file 0 => $DIR/loop_break_value.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 4, 1) to (start + 10, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 2, 13) to (start + 5, 10) +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/loop_break_value.coverage b/tests/coverage/loop_break_value.coverage index 7d4533987594..5e80168b958b 100644 --- a/tests/coverage/loop_break_value.coverage +++ b/tests/coverage/loop_break_value.coverage @@ -3,13 +3,13 @@ LL| |#[rustfmt::skip] LL| 1|fn main() { LL| 1| let result - LL| 1| = + LL| | = LL| 1| loop LL| 1| { LL| 1| break LL| 1| 10 LL| 1| ; LL| 1| } - LL| 1| ; + LL| | ; LL| 1|} diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index d414710ee9d6..78fdaa53f46f 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,5 +1,5 @@ Function name: ::fmt -Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 17, 0d, 00, 18, 00, 19, 0d, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs Number of expressions: 4 @@ -7,13 +7,16 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Counter(3) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16) -- Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21) +Number of file 0 mappings: 25 +- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 21) - Code(Zero) at (prev + 1, 23) to (start + 0, 27) - Code(Zero) at (prev + 0, 28) to (start + 0, 30) - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) - Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) - Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14) @@ -23,7 +26,9 @@ Number of file 0 mappings: 20 - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(3)) at (prev + 0, 24) to (start + 0, 25) +- Code(Counter(3)) at (prev + 0, 27) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) = ((c0 + c3) - (c1 + c2)) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) @@ -33,7 +38,7 @@ Number of file 0 mappings: 20 Highest counter ID seen: c3 Function name: ::fmt -Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs Number of expressions: 4 @@ -41,14 +46,17 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Counter(1), rhs = Counter(3) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17) -- Code(Zero) at (prev + 1, 18) to (start + 1, 10) +Number of file 0 mappings: 25 +- Code(Counter(0)) at (prev + 34, 5) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 17) +- Code(Zero) at (prev + 0, 18) to (start + 1, 10) - Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21) - Code(Zero) at (prev + 1, 23) to (start + 0, 27) - Code(Zero) at (prev + 0, 28) to (start + 0, 30) - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) - Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31) - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23) @@ -58,7 +66,9 @@ Number of file 0 mappings: 20 - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) -- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25) +- Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) = ((c0 + c2) - (c1 + c3)) - Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) @@ -67,11 +77,20 @@ Number of file 0 mappings: 20 Highest counter ID seen: c3 Function name: loops_branches::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02] +Raw bytes (54): 0x[01, 01, 00, 0a, 01, 37, 01, 00, 0a, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 09, 00, 15, 01, 00, 18, 00, 23, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/loops_branches.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 55, 1) to (start + 5, 2) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 35) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/macro_in_closure.cov-map b/tests/coverage/macro_in_closure.cov-map index 3e71ed877bf9..4544aa50143e 100644 --- a/tests/coverage/macro_in_closure.cov-map +++ b/tests/coverage/macro_in_closure.cov-map @@ -1,18 +1,21 @@ Function name: macro_in_closure::NO_BLOCK::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 1c, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 25, 00, 2c] Number of files: 1 - file 0 => $DIR/macro_in_closure.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 28) to (start + 0, 45) +- Code(Counter(0)) at (prev + 7, 37) to (start + 0, 44) Highest counter ID seen: c0 Function name: macro_in_closure::WITH_BLOCK::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 1e, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 1e, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 15, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/macro_in_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 9, 30) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 9, 30) to (start + 0, 31) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map index 18b4e28b7b43..c96cb75846b2 100644 --- a/tests/coverage/macro_name_span.cov-map +++ b/tests/coverage/macro_name_span.cov-map @@ -1,18 +1,21 @@ Function name: macro_name_span::affected_function -Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 3e] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 1c, 00, 1d, 01, 01, 09, 00, 3e] Number of files: 1 - file 0 => $DIR/macro_name_span.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 62) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 62) Highest counter ID seen: c0 Function name: macro_name_span::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/macro_name_span.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map index a29c712998f7..0bb126bc09b1 100644 --- a/tests/coverage/match_or_pattern.cov-map +++ b/tests/coverage/match_or_pattern.cov-map @@ -1,5 +1,5 @@ Function name: match_or_pattern::main -Raw bytes (145): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02] +Raw bytes (190): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 22, 01, 01, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 08, 00, 0f, 05, 00, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/match_or_pattern.rs Number of expressions: 8 @@ -11,9 +11,18 @@ Number of expressions: 8 - expression 5 operands: lhs = Counter(0), rhs = Counter(6) - expression 6 operands: lhs = Counter(0), rhs = Counter(7) - expression 7 operands: lhs = Counter(0), rhs = Counter(8) -Number of file 0 mappings: 25 -- Code(Counter(0)) at (prev + 1, 1) to (start + 8, 15) -- Code(Counter(1)) at (prev + 8, 16) to (start + 3, 6) +Number of file 0 mappings: 34 +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18) +- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18) +- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 3, 6) - Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17) diff --git a/tests/coverage/match_or_pattern.coverage b/tests/coverage/match_or_pattern.coverage index a65c226e5672..50540bc5614a 100644 --- a/tests/coverage/match_or_pattern.coverage +++ b/tests/coverage/match_or_pattern.coverage @@ -1,9 +1,9 @@ LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut a: u8 = 0; LL| 1| let mut b: u8 = 0; LL| 1| if is_true { diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map index f966d754f540..ffee97cfbc50 100644 --- a/tests/coverage/mcdc/condition-limit.cov-map +++ b/tests/coverage/mcdc/condition-limit.cov-map @@ -1,5 +1,5 @@ Function name: condition_limit::accept_7_conditions -Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (192): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 1b, 01, 06, 01, 00, 2c, 01, 01, 0a, 00, 0b, 01, 00, 0d, 00, 0e, 01, 00, 10, 00, 11, 01, 00, 13, 00, 14, 01, 00, 16, 00, 17, 01, 00, 19, 00, 1a, 01, 00, 1c, 00, 1d, 01, 00, 21, 00, 29, 01, 01, 08, 00, 09, 28, 08, 07, 00, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/condition-limit.rs Number of expressions: 8 @@ -11,9 +11,18 @@ Number of expressions: 8 - expression 5 operands: lhs = Counter(5), rhs = Counter(6) - expression 6 operands: lhs = Counter(6), rhs = Counter(7) - expression 7 operands: lhs = Counter(0), rhs = Counter(7) -Number of file 0 mappings: 18 -- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 9) -- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39) +Number of file 0 mappings: 27 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 44) +- Code(Counter(0)) at (prev + 1, 10) to (start + 0, 11) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 20) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 0, 8) to (start + 0, 39) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map index de4ea7790f75..dac1eb4c94bd 100644 --- a/tests/coverage/mcdc/if.cov-map +++ b/tests/coverage/mcdc/if.cov-map @@ -1,14 +1,15 @@ Function name: if::mcdc_check_a -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 0e, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -23,16 +24,17 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_b -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 16, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -47,16 +49,17 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_both -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 1e, 01, 00, 25, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -71,16 +74,17 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_neither -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 06, 01, 00, 28, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 40) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -95,7 +99,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_not_tree_decision -Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (90): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0b, 01, 30, 01, 00, 3b, 28, 05, 03, 03, 08, 00, 15, 01, 00, 09, 00, 0a, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 7 @@ -106,9 +110,10 @@ Number of expressions: 7 - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) - expression 5 operands: lhs = Counter(1), rhs = Counter(2) - expression 6 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 48, 1) to (start + 3, 10) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 59) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10) true = c1 false = (c0 - c1) @@ -129,7 +134,7 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: if::mcdc_check_tree_decision -Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (92): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0b, 01, 26, 01, 00, 37, 01, 03, 08, 00, 09, 28, 04, 03, 00, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs Number of expressions: 8 @@ -141,9 +146,10 @@ Number of expressions: 8 - expression 5 operands: lhs = Counter(2), rhs = Counter(3) - expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add) - expression 7 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 38, 1) to (start + 3, 9) -- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 55) +- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 8) to (start + 0, 21) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -164,46 +170,53 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: if::mcdc_nested_if -Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (139): 0x[01, 01, 0d, 01, 05, 01, 33, 05, 09, 05, 09, 05, 09, 05, 09, 33, 0d, 05, 09, 0d, 11, 33, 11, 05, 09, 01, 33, 05, 09, 11, 01, 3a, 01, 00, 2d, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 2e, 02, 00, 00, 00, 0d, 00, 0e, 33, 01, 09, 00, 0c, 33, 00, 0d, 00, 15, 33, 01, 0c, 00, 0d, 28, 06, 02, 00, 0c, 00, 12, 30, 0d, 1a, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 22, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 26, 02, 09, 00, 0a, 2e, 01, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/if.rs -Number of expressions: 11 +Number of expressions: 13 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(10, Add) +- expression 1 operands: lhs = Counter(0), rhs = Expression(12, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Expression(10, Add), rhs = Counter(3) +- expression 4 operands: lhs = Counter(1), rhs = Counter(2) - expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(3), rhs = Counter(4) -- expression 7 operands: lhs = Expression(10, Add), rhs = Counter(4) -- expression 8 operands: lhs = Counter(1), rhs = Counter(2) -- expression 9 operands: lhs = Counter(0), rhs = Expression(10, Add) +- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(3) +- expression 7 operands: lhs = Counter(1), rhs = Counter(2) +- expression 8 operands: lhs = Counter(3), rhs = Counter(4) +- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(4) - expression 10 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 58, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) +- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add) +- expression 12 operands: lhs = Counter(1), rhs = Counter(2) +Number of file 0 mappings: 17 +- Code(Counter(0)) at (prev + 58, 1) to (start + 0, 45) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) - Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14) = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) +- MCDCBranch { true: Counter(2), false: Expression(11, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) true = c2 false = (c0 - (c1 + c2)) -- Code(Expression(10, Add)) at (prev + 1, 9) to (start + 1, 13) +- Code(Expression(12, Add)) at (prev + 1, 9) to (start + 0, 12) = (c1 + c2) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 12) to (start + 0, 18) -- MCDCBranch { true: Counter(3), false: Expression(4, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13) +- Code(Expression(12, Add)) at (prev + 0, 13) to (start + 0, 21) + = (c1 + c2) +- Code(Expression(12, Add)) at (prev + 1, 12) to (start + 0, 13) + = (c1 + c2) +- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 12) to (start + 0, 18) +- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13) true = c3 false = ((c1 + c2) - c3) - Code(Counter(3)) at (prev + 0, 17) to (start + 0, 18) -- MCDCBranch { true: Counter(4), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18) +- MCDCBranch { true: Counter(4), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18) true = c4 false = (c3 - c4) - Code(Counter(4)) at (prev + 0, 19) to (start + 2, 10) -- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(9, Sub)) at (prev + 2, 9) to (start + 0, 10) = ((c1 + c2) - c4) -- Code(Expression(9, Sub)) at (prev + 1, 12) to (start + 2, 6) +- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 2, 6) = (c0 - (c1 + c2)) - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c4 diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage index 51917d060454..fda5525c472c 100644 --- a/tests/coverage/mcdc/if.coverage +++ b/tests/coverage/mcdc/if.coverage @@ -123,8 +123,8 @@ LL| 3|} LL| | LL| 4|fn mcdc_check_tree_decision(a: bool, b: bool, c: bool) { - LL| 4| // This expression is intentionally written in a way - LL| 4| // where 100% branch coverage indicates 100% mcdc coverage. + LL| | // This expression is intentionally written in a way + LL| | // where 100% branch coverage indicates 100% mcdc coverage. LL| 4| if a && (b || c) { ^3 ^2 ------------------ @@ -160,8 +160,8 @@ LL| 4|} LL| | LL| 4|fn mcdc_check_not_tree_decision(a: bool, b: bool, c: bool) { - LL| 4| // Contradict to `mcdc_check_tree_decision`, - LL| 4| // 100% branch coverage of this expression does not indicate 100% mcdc coverage. + LL| | // Contradict to `mcdc_check_tree_decision`, + LL| | // 100% branch coverage of this expression does not indicate 100% mcdc coverage. LL| 4| if (a || b) && c { ^1 ------------------ diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map index 714d168cf498..d05ef368ba4a 100644 --- a/tests/coverage/mcdc/inlined_expressions.cov-map +++ b/tests/coverage/mcdc/inlined_expressions.cov-map @@ -1,13 +1,14 @@ Function name: inlined_expressions::inlined_instance -Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (55): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 07, 01, 00, 2e, 01, 01, 05, 00, 06, 28, 03, 02, 00, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inlined_expressions.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 6) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 5) to (start + 0, 11) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6) true = c1 false = (c0 - c1) diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map index 7232e4f89cdd..853cdf2c5760 100644 --- a/tests/coverage/mcdc/nested_if.cov-map +++ b/tests/coverage/mcdc/nested_if.cov-map @@ -1,5 +1,5 @@ Function name: nested_if::doubly_nested_if_in_condition -Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 15, 01, 0e, 01, 00, 45, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_if.rs Number of expressions: 15 @@ -18,9 +18,10 @@ Number of expressions: 15 - expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add) - expression 13 operands: lhs = Counter(2), rhs = Counter(3) - expression 14 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78) +Number of file 0 mappings: 21 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 69) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 78) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -59,7 +60,7 @@ Number of file 0 mappings: 20 Highest counter ID seen: c6 Function name: nested_if::nested_if_in_condition -Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (123): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0f, 01, 06, 01, 00, 35, 01, 01, 08, 00, 09, 28, 06, 02, 00, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_if.rs Number of expressions: 10 @@ -73,9 +74,10 @@ Number of expressions: 10 - expression 7 operands: lhs = Counter(1), rhs = Expression(8, Add) - expression 8 operands: lhs = Counter(2), rhs = Counter(3) - expression 9 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46) +Number of file 0 mappings: 15 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 53) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 46) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -103,7 +105,7 @@ Number of file 0 mappings: 14 Highest counter ID seen: c4 Function name: nested_if::nested_in_then_block_in_condition -Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 15, 01, 21, 01, 00, 52, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_if.rs Number of expressions: 15 @@ -122,9 +124,10 @@ Number of expressions: 15 - expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add) - expression 13 operands: lhs = Counter(2), rhs = Counter(3) - expression 14 operands: lhs = Counter(0), rhs = Counter(6) -Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 9) -- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75) +Number of file 0 mappings: 21 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 82) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 75) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) @@ -163,7 +166,7 @@ Number of file 0 mappings: 20 Highest counter ID seen: c6 Function name: nested_if::nested_single_condition_decision -Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (88): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0c, 01, 16, 01, 00, 36, 01, 04, 08, 00, 09, 28, 03, 02, 00, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_if.rs Number of expressions: 5 @@ -172,9 +175,10 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) - expression 4 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 22, 1) to (start + 4, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 54) +- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 9) +- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 41) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage index c3ac30d22bf8..8b5179b34fee 100644 --- a/tests/coverage/mcdc/nested_if.coverage +++ b/tests/coverage/mcdc/nested_if.coverage @@ -122,9 +122,9 @@ LL| 4|} LL| | LL| 3|fn nested_single_condition_decision(a: bool, b: bool) { - LL| 3| // Decision with only 1 decision should not be instrumented by MCDC because - LL| 3| // branch-coverage is equivalent to MCDC coverage in this case, and we don't - LL| 3| // want to waste bitmap space for this. + LL| | // Decision with only 1 decision should not be instrumented by MCDC because + LL| | // branch-coverage is equivalent to MCDC coverage in this case, and we don't + LL| | // want to waste bitmap space for this. LL| 3| if a && if b { false } else { true } { ^2 ^1 ^1 ------------------ diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map index 02251e691522..f06bc2ed8168 100644 --- a/tests/coverage/mcdc/non_control_flow.cov-map +++ b/tests/coverage/mcdc/non_control_flow.cov-map @@ -1,5 +1,5 @@ Function name: non_control_flow::assign_3 -Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (89): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0c, 01, 15, 01, 00, 27, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 4 @@ -7,8 +7,8 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 40) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 39) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) @@ -24,11 +24,13 @@ Number of file 0 mappings: 10 - MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) true = c3 false = (c2 - c3) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: non_control_flow::assign_3_bis -Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (91): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0c, 01, 1a, 01, 00, 2b, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 5 @@ -37,8 +39,8 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) - expression 4 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 44) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 43) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) @@ -54,18 +56,20 @@ Number of file 0 mappings: 10 - MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) true = c3 false = (c0 - (c2 + c3)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: non_control_flow::assign_and -Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (70): 0x[01, 01, 02, 01, 05, 05, 09, 0a, 01, 0b, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 33) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 32) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) @@ -76,19 +80,21 @@ Number of file 0 mappings: 8 - MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c1 - c2) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: non_control_flow::assign_or -Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (72): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 32) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 31) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) @@ -100,27 +106,32 @@ Number of file 0 mappings: 8 - MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c0 - (c1 + c2)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: non_control_flow::foo -Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 24, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: non_control_flow::func_call -Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] +Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 31) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8) - Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 9) to (start + 0, 15) @@ -135,7 +146,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: non_control_flow::right_comb_tree -Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02] +Raw bytes (121): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 10, 01, 1f, 01, 00, 40, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/non_control_flow.rs Number of expressions: 5 @@ -144,8 +155,8 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(2), rhs = Counter(3) - expression 3 operands: lhs = Counter(3), rhs = Counter(4) - expression 4 operands: lhs = Counter(4), rhs = Counter(5) -Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 65) +Number of file 0 mappings: 16 +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 64) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42) @@ -168,6 +179,8 @@ Number of file 0 mappings: 14 - MCDCBranch { true: Counter(5), false: Expression(4, Sub), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39) true = c5 false = (c4 - c5) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c5 diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map index 4a35da13a847..649c65d8590b 100644 --- a/tests/coverage/nested_loops.cov-map +++ b/tests/coverage/nested_loops.cov-map @@ -1,40 +1,60 @@ Function name: nested_loops::main -Raw bytes (97): 0x[01, 01, 0e, 07, 2f, 05, 11, 01, 0d, 2f, 05, 01, 0d, 27, 05, 01, 09, 33, 27, 05, 15, 01, 09, 2f, 33, 01, 0d, 05, 15, 05, 01, 0d, 01, 01, 01, 02, 1b, 05, 04, 13, 00, 20, 09, 01, 0d, 01, 18, 0d, 02, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 0e, 01, 0e, 03, 16, 15, 04, 11, 01, 1b, 16, 02, 15, 00, 21, 1e, 01, 18, 02, 12, 2a, 03, 0d, 00, 0e, 36, 02, 09, 00, 17, 01, 02, 01, 00, 02] +Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 11, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 0d, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 0d, 01, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_loops.rs -Number of expressions: 14 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(11, Add) +Number of expressions: 20 +- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(17, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(4) - expression 2 operands: lhs = Counter(0), rhs = Counter(3) -- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(1) +- expression 3 operands: lhs = Expression(17, Add), rhs = Counter(1) - expression 4 operands: lhs = Counter(0), rhs = Counter(3) -- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(1) -- expression 6 operands: lhs = Counter(0), rhs = Counter(2) -- expression 7 operands: lhs = Expression(12, Add), rhs = Expression(9, Add) -- expression 8 operands: lhs = Counter(1), rhs = Counter(5) -- expression 9 operands: lhs = Counter(0), rhs = Counter(2) -- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add) -- expression 11 operands: lhs = Counter(0), rhs = Counter(3) -- expression 12 operands: lhs = Counter(1), rhs = Counter(5) -- expression 13 operands: lhs = Counter(1), rhs = Counter(0) -Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 1, 1) to (start + 2, 27) -- Code(Counter(1)) at (prev + 4, 19) to (start + 0, 32) -- Code(Counter(2)) at (prev + 1, 13) to (start + 1, 24) -- Code(Counter(3)) at (prev + 2, 18) to (start + 0, 23) +- expression 5 operands: lhs = Expression(17, Add), rhs = Counter(1) +- expression 6 operands: lhs = Counter(0), rhs = Counter(3) +- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(1) +- expression 8 operands: lhs = Counter(0), rhs = Counter(3) +- expression 9 operands: lhs = Expression(17, Add), rhs = Counter(1) +- expression 10 operands: lhs = Counter(0), rhs = Counter(3) +- expression 11 operands: lhs = Expression(15, Add), rhs = Counter(1) +- expression 12 operands: lhs = Counter(0), rhs = Counter(2) +- expression 13 operands: lhs = Expression(18, Add), rhs = Expression(15, Add) +- expression 14 operands: lhs = Counter(1), rhs = Counter(5) +- expression 15 operands: lhs = Counter(0), rhs = Counter(2) +- expression 16 operands: lhs = Expression(17, Add), rhs = Expression(18, Add) +- expression 17 operands: lhs = Counter(0), rhs = Counter(3) +- expression 18 operands: lhs = Counter(1), rhs = Counter(5) +- expression 19 operands: lhs = Counter(1), rhs = Counter(0) +Number of file 0 mappings: 24 +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 2, 19) to (start + 0, 32) +- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18) +- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) +- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18) +- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) +- Code(Counter(3)) at (prev + 1, 18) to (start + 0, 23) - Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22) - Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22) = ((c1 + c4) - (c0 + c3)) -- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 3, 22) +- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 14) = ((c0 + c3) - c1) -- Code(Counter(5)) at (prev + 4, 17) to (start + 1, 27) -- Code(Expression(5, Sub)) at (prev + 2, 21) to (start + 0, 33) +- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) + = ((c0 + c3) - c1) +- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) + = ((c0 + c3) - c1) +- Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 22) + = ((c0 + c3) - c1) +- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 24) +- Code(Counter(5)) at (prev + 1, 20) to (start + 0, 27) +- Code(Expression(11, Sub)) at (prev + 1, 21) to (start + 0, 33) = ((c0 + c2) - c1) -- Code(Expression(7, Sub)) at (prev + 1, 24) to (start + 2, 18) +- Code(Expression(13, Sub)) at (prev + 1, 24) to (start + 2, 18) = ((c1 + c5) - (c0 + c2)) -- Code(Expression(10, Sub)) at (prev + 3, 13) to (start + 0, 14) +- Code(Expression(16, Sub)) at (prev + 3, 13) to (start + 0, 14) = ((c0 + c3) - (c1 + c5)) -- Code(Expression(13, Sub)) at (prev + 2, 9) to (start + 0, 23) +- Code(Expression(19, Sub)) at (prev + 2, 9) to (start + 0, 23) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c5 diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map index 89012b0ab917..f2867008127b 100644 --- a/tests/coverage/no-core.cov-map +++ b/tests/coverage/no-core.cov-map @@ -1,9 +1,10 @@ Function name: no_core::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0c, 01, 00, 0a, 01, 00, 0c, 00, 0d] Number of files: 1 - file 0 => $DIR/no-core.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) Highest counter ID seen: c0 diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map index caef09355d22..ca3c95fe84c4 100644 --- a/tests/coverage/no_cov_crate.cov-map +++ b/tests/coverage/no_cov_crate.cov-map @@ -1,68 +1,99 @@ Function name: no_cov_crate::add_coverage_1 -Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 22, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_2 -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 1a, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_not_called (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 00, 1d, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 26, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 31, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 31, 1) to (start + 0, 29) +- Code(Zero) at (prev + 1, 5) to (start + 0, 13) +- Code(Zero) at (prev + 0, 14) to (start + 0, 38) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: no_cov_crate::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 4f, 01, 0b, 02] +Raw bytes (74): 0x[01, 01, 00, 0e, 01, 4f, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 05, 00, 1a, 01, 01, 05, 00, 1a, 01, 01, 05, 00, 13, 01, 01, 05, 00, 13, 01, 02, 05, 00, 22, 01, 00, 23, 00, 2a, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1e, 01, 01, 05, 00, 23, 01, 00, 24, 00, 2b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 79, 1) to (start + 11, 2) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 34) +- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 42) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 35) +- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 43) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer -Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 22, 01, 0c, 05, 00, 06] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 05, 00, 20, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 1a, 01, 00, 1b, 00, 22, 01, 0a, 05, 00, 06] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 51, 5) to (start + 2, 34) -- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 51, 5) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26) +- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34) +- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered -Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 16, 01, 0b, 05, 00, 06] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 41, 05, 00, 2d, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 0e, 01, 00, 0f, 00, 16, 01, 09, 05, 00, 06] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 65, 5) to (start + 2, 22) -- Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 45) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22) +- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered::inner -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 45, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 45, 09, 00, 20, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 - file 0 => $DIR/no_cov_crate.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 69, 9) to (start + 1, 23) -- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 69, 9) to (start + 0, 32) +- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23) +- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14) - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14) = (c0 - c1) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10) diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage index 2a8961e6c93a..c6453e60a1a4 100644 --- a/tests/coverage/no_cov_crate.coverage +++ b/tests/coverage/no_cov_crate.coverage @@ -78,12 +78,12 @@ LL| | LL| 1|fn main() { LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| do_not_add_coverage_1(); LL| 1| do_not_add_coverage_2(); LL| 1| add_coverage_1(); LL| 1| add_coverage_2(); - LL| 1| + LL| | LL| 1| nested_fns::outer_not_covered(is_true); LL| 1| nested_fns::outer(is_true); LL| 1| nested_fns::outer_both_covered(is_true); diff --git a/tests/coverage/no_spans.cov-map b/tests/coverage/no_spans.cov-map index 992247fd520b..821976b0fab0 100644 --- a/tests/coverage/no_spans.cov-map +++ b/tests/coverage/no_spans.cov-map @@ -1,18 +1,20 @@ Function name: no_spans::affected_function -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 1c, 00, 1d] Number of files: 1 - file 0 => $DIR/no_spans.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 21, 28) to (start + 0, 29) Highest counter ID seen: c0 -Function name: no_spans::affected_function::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e] +Function name: no_spans::main +Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_spans.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/no_spans.coverage b/tests/coverage/no_spans.coverage index 19e8c2fe5b6b..cf0e47677e9a 100644 --- a/tests/coverage/no_spans.coverage +++ b/tests/coverage/no_spans.coverage @@ -1,20 +1,15 @@ LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | - LL| |// If the span extractor can't find any relevant spans for a function, the - LL| |// refinement loop will terminate with nothing in its `prev` slot. If the - LL| |// subsequent code tries to unwrap `prev`, it will panic. + LL| |// Test that coverage instrumentation can gracefully handle functions that end + LL| |// up having no relevant spans, without crashing the compiler or causing + LL| |// `llvm-cov` to fail. LL| |// - LL| |// This scenario became more likely after #118525 started discarding spans that - LL| |// can't be un-expanded back to within the function body. - LL| |// - LL| |// Regression test for "invalid attempt to unwrap a None some_prev", as seen - LL| |// in issues such as #118643 and #118662. + LL| |// This was originally a regression test for issues such as #118643 and #118662. LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | affected_function()(); - LL| |} + LL| 1|fn main() { + LL| 1| affected_function()(); + LL| 1|} LL| | LL| |macro_rules! macro_that_defines_a_function { LL| | (fn $name:ident () $body:tt) => { @@ -24,7 +19,7 @@ LL| | LL| |macro_that_defines_a_function! { LL| 1| fn affected_function() { - LL| 1| || () + LL| | || () LL| | } LL| |} diff --git a/tests/coverage/no_spans.rs b/tests/coverage/no_spans.rs index e5312406f8a1..979b40719277 100644 --- a/tests/coverage/no_spans.rs +++ b/tests/coverage/no_spans.rs @@ -1,17 +1,12 @@ #![feature(coverage_attribute)] //@ edition: 2021 -// If the span extractor can't find any relevant spans for a function, the -// refinement loop will terminate with nothing in its `prev` slot. If the -// subsequent code tries to unwrap `prev`, it will panic. +// Test that coverage instrumentation can gracefully handle functions that end +// up having no relevant spans, without crashing the compiler or causing +// `llvm-cov` to fail. // -// This scenario became more likely after #118525 started discarding spans that -// can't be un-expanded back to within the function body. -// -// Regression test for "invalid attempt to unwrap a None some_prev", as seen -// in issues such as #118643 and #118662. +// This was originally a regression test for issues such as #118643 and #118662. -#[coverage(off)] fn main() { affected_function()(); } diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map index 9d4fc074111f..c8aa5c7527d2 100644 --- a/tests/coverage/no_spans_if_not.cov-map +++ b/tests/coverage/no_spans_if_not.cov-map @@ -1,20 +1,23 @@ Function name: no_spans_if_not::affected_function -Raw bytes (19): 0x[01, 01, 00, 03, 01, 16, 1c, 01, 12, 01, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 1c, 00, 1d, 01, 01, 0c, 00, 12, 01, 01, 0d, 00, 0f, 00, 02, 0d, 00, 0f] Number of files: 1 - file 0 => $DIR/no_spans_if_not.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18) -- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 15) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 15) - Code(Zero) at (prev + 2, 13) to (start + 0, 15) Highest counter ID seen: c0 Function name: no_spans_if_not::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/no_spans_if_not.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map index 9bb68ee107dd..18b0503b9e7c 100644 --- a/tests/coverage/overflow.cov-map +++ b/tests/coverage/overflow.cov-map @@ -1,5 +1,5 @@ Function name: overflow::main -Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 10, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 06, 03, 13, 00, 20, 0d, 00, 21, 03, 0a, 0e, 03, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] +Raw bytes (96): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 10, 01, 10, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 09, 01, 11, 00, 17, 09, 00, 1a, 00, 28, 06, 02, 13, 00, 20, 0d, 00, 21, 03, 0a, 0d, 01, 11, 00, 17, 0d, 00, 1a, 00, 28, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/overflow.rs Number of expressions: 6 @@ -9,33 +9,50 @@ Number of expressions: 6 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) - expression 5 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 27) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24) +Number of file 0 mappings: 16 +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24) - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26) = (c1 - c0) - Code(Counter(2)) at (prev + 0, 27) to (start + 3, 10) -- Code(Expression(1, Sub)) at (prev + 3, 19) to (start + 0, 32) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 40) +- Code(Expression(1, Sub)) at (prev + 2, 19) to (start + 0, 32) = (c1 - (c0 + c2)) - Code(Counter(3)) at (prev + 0, 33) to (start + 3, 10) -- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 10) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 40) +- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c1 - ((c0 + c2) + c3)) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23) = (c1 - c0) -- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: overflow::might_overflow -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 05, 02] +Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 05, 01, 00, 26, 01, 01, 08, 00, 12, 05, 00, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1e, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 21, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/overflow.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 18) -- Code(Counter(1)) at (prev + 1, 19) to (start + 2, 6) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 19) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 9) to (start + 5, 2) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 33) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 47) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map index f6d1fe5b9b48..ff656d3d8d58 100644 --- a/tests/coverage/panic_unwind.cov-map +++ b/tests/coverage/panic_unwind.cov-map @@ -1,5 +1,5 @@ Function name: panic_unwind::main -Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02] +Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/panic_unwind.rs Number of expressions: 6 @@ -9,9 +9,11 @@ Number of expressions: 6 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) - expression 5 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24) - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26) = (c1 - c0) - Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10) @@ -22,19 +24,25 @@ Number of file 0 mappings: 9 = (c1 - ((c0 + c2) + c3)) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23) = (c1 - c0) -- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: panic_unwind::might_panic -Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02] +Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 04, 01, 00, 23, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 20, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/panic_unwind.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20) -- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15) -- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2) +Number of file 0 mappings: 7 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 35) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 32) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15) +- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6) + = (c0 - c1) +- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2) = (c0 - c1) Highest counter ID seen: c1 diff --git a/tests/coverage/partial_eq.cov-map b/tests/coverage/partial_eq.cov-map index 02054aa444a5..0a81be749128 100644 --- a/tests/coverage/partial_eq.cov-map +++ b/tests/coverage/partial_eq.cov-map @@ -1,18 +1,29 @@ Function name: ::new -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 05, 02, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 0c, 05, 00, 41, 01, 01, 09, 00, 25, 01, 00, 10, 00, 15, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/partial_eq.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 5) to (start + 2, 6) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 65) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: partial_eq::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 0a, 02] +Raw bytes (49): 0x[01, 01, 00, 09, 01, 11, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 02, 05, 00, 0d, 01, 01, 09, 00, 1b, 01, 03, 09, 00, 26, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/partial_eq.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 1) to (start + 10, 2) +Number of file 0 mappings: 9 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 27) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 38) +- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/partial_eq.coverage b/tests/coverage/partial_eq.coverage index dc5b82b3c5f1..0662ce2c3000 100644 --- a/tests/coverage/partial_eq.coverage +++ b/tests/coverage/partial_eq.coverage @@ -17,13 +17,13 @@ LL| 1|fn main() { LL| 1| let version_3_2_1 = Version::new(3, 2, 1); LL| 1| let version_3_3_0 = Version::new(3, 3, 0); - LL| 1| + LL| | LL| 1| println!( LL| 1| "{:?} < {:?} = {}", - LL| 1| version_3_2_1, - LL| 1| version_3_3_0, + LL| | version_3_2_1, + LL| | version_3_3_0, LL| 1| version_3_2_1 < version_3_3_0, // - LL| 1| ); + LL| | ); LL| 1|} LL| | LL| |/* diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map index 542c93cbfa05..5447ffdb6e7c 100644 --- a/tests/coverage/simple_loop.cov-map +++ b/tests/coverage/simple_loop.cov-map @@ -1,19 +1,27 @@ Function name: simple_loop::main -Raw bytes (43): 0x[01, 01, 02, 01, 05, 09, 01, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 06, 02, 0a, 03, 0a, 01, 06, 01, 00, 02] +Raw bytes (75): 0x[01, 01, 03, 01, 05, 09, 01, 09, 01, 0d, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 0a, 02, 09, 00, 0a, 0a, 01, 09, 02, 0a, 01, 05, 01, 00, 02] Number of files: 1 - file 0 => $DIR/simple_loop.rs -Number of expressions: 2 +Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(2), rhs = Counter(0) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 4, 1) to (start + 9, 16) -- Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6) +- expression 2 operands: lhs = Counter(2), rhs = Counter(0) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6) - Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14) - Code(Counter(0)) at (prev + 4, 13) to (start + 0, 18) -- Code(Expression(1, Sub)) at (prev + 2, 10) to (start + 3, 10) +- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c2 - c0) -- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 2) +- Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 2, 10) + = (c2 - c0) +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2) Highest counter ID seen: c2 diff --git a/tests/coverage/simple_loop.coverage b/tests/coverage/simple_loop.coverage index 237e509f42e1..a75263f633e5 100644 --- a/tests/coverage/simple_loop.coverage +++ b/tests/coverage/simple_loop.coverage @@ -2,14 +2,14 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut countdown = 0; - LL| 1| - LL| 1| if + LL| | + LL| | if LL| 1| is_true LL| 1| { LL| 1| countdown diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map index a96ddc2bb9ae..cbd6c7ca52fd 100644 --- a/tests/coverage/simple_match.cov-map +++ b/tests/coverage/simple_match.cov-map @@ -1,5 +1,5 @@ Function name: simple_match::main -Raw bytes (64): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0e, 0a, 0d, 00, 0f, 01, 03, 01, 00, 02] +Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/simple_match.rs Number of expressions: 5 @@ -8,9 +8,14 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(2), rhs = Counter(0) - expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add) - expression 4 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15) -- Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6) +Number of file 0 mappings: 17 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13) @@ -20,7 +25,9 @@ Number of file 0 mappings: 10 - Code(Expression(2, Sub)) at (prev + 2, 17) to (start + 2, 18) = (c2 - c0) - Code(Counter(3)) at (prev + 4, 13) to (start + 7, 14) -- Code(Expression(3, Sub)) at (prev + 10, 13) to (start + 0, 15) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 30) +- Code(Counter(3)) at (prev + 2, 21) to (start + 0, 22) +- Code(Expression(3, Sub)) at (prev + 7, 13) to (start + 0, 15) = (c2 - (c0 + c3)) - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c3 diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage index e1d5e48a2bf1..0ed7e8dc7887 100644 --- a/tests/coverage/simple_match.coverage +++ b/tests/coverage/simple_match.coverage @@ -2,11 +2,11 @@ LL| | LL| |#[rustfmt::skip] LL| 1|fn main() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| + LL| | LL| 1| let mut countdown = 1; LL| 1| if is_true { LL| 1| countdown = 0; diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map index b0d260efeb9a..70cf7cff4b67 100644 --- a/tests/coverage/sort_groups.cov-map +++ b/tests/coverage/sort_groups.cov-map @@ -1,79 +1,98 @@ Function name: sort_groups::generic_fn::<&str> -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12) -- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: sort_groups::generic_fn::<()> -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12) -- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: sort_groups::generic_fn:: -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12) -- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: sort_groups::generic_fn:: -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12) -- Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12) +- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: sort_groups::main -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 1c, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02] +Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 01, 05, 00, 15, 01, 00, 16, 00, 1a, 01, 01, 05, 00, 1f, 01, 00, 20, 00, 25, 01, 01, 08, 00, 1c, 05, 00, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1b, 01, 01, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 6, 1) to (start + 4, 28) -- Code(Counter(1)) at (prev + 4, 36) to (start + 2, 6) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21) +- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31) +- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 28) +- Code(Counter(1)) at (prev + 0, 36) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 5) to (start + 2, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 27) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: sort_groups::other_fn -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 11] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 17, 01, 00, 0e, 01, 00, 10, 00, 11] Number of files: 1 - file 0 => $DIR/sort_groups.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 17) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17) Highest counter ID seen: c0 diff --git a/tests/coverage/test_harness.cov-map b/tests/coverage/test_harness.cov-map index 50654fb22137..691332a1c420 100644 --- a/tests/coverage/test_harness.cov-map +++ b/tests/coverage/test_harness.cov-map @@ -1,18 +1,20 @@ Function name: test_harness::my_test -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 10] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 00, 0d, 01, 00, 0f, 00, 10] Number of files: 1 - file 0 => $DIR/test_harness.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 16) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) Highest counter ID seen: c0 Function name: test_harness::unused (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 07, 01, 00, 0c, 00, 00, 0e, 00, 0f] Number of files: 1 - file 0 => $DIR/test_harness.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 7, 1) to (start + 0, 15) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 7, 1) to (start + 0, 12) +- Code(Zero) at (prev + 0, 14) to (start + 0, 15) Highest counter ID seen: (none) diff --git a/tests/coverage/tight_inf_loop.cov-map b/tests/coverage/tight_inf_loop.cov-map index 31581f0872f9..c6bee3bd7ad9 100644 --- a/tests/coverage/tight_inf_loop.cov-map +++ b/tests/coverage/tight_inf_loop.cov-map @@ -1,11 +1,13 @@ Function name: tight_inf_loop::main -Raw bytes (19): 0x[01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 01, 01, 06, 01, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 01, 01, 00, 0a, 01, 01, 08, 00, 0d, 00, 01, 09, 00, 10, 01, 01, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/tight_inf_loop.rs Number of expressions: 0 -Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 13) -- Code(Zero) at (prev + 2, 9) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 6) to (start + 1, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 13) +- Code(Zero) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/trivial.cov-map b/tests/coverage/trivial.cov-map index 0064b20480f3..fff10df9aee5 100644 --- a/tests/coverage/trivial.cov-map +++ b/tests/coverage/trivial.cov-map @@ -1,9 +1,10 @@ Function name: trivial::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d] Number of files: 1 - file 0 => $DIR/trivial.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) Highest counter ID seen: c0 diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index a6ecc68ab0e8..e08f42961532 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -1,61 +1,68 @@ Function name: ::get_thing_2 -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 29, 05, 00, 44, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 41, 5) to (start + 1, 24) -- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 41, 5) to (start + 0, 68) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24) +- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 26) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: ::call -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 34, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 34, 05, 00, 3a, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 52, 5) to (start + 1, 24) -- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 52, 5) to (start + 0, 58) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24) +- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6) Highest counter ID seen: c1 Function name: try_error_result::call -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 14, 05, 02, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 20) -- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: try_error_result::main -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0a, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (46): 0x[01, 01, 01, 01, 05, 08, 01, 71, 01, 00, 1c, 01, 01, 05, 00, 0a, 01, 00, 0d, 00, 17, 01, 00, 18, 00, 2b, 01, 01, 05, 00, 0a, 05, 01, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 113, 1) to (start + 2, 10) -- Code(Counter(1)) at (prev + 3, 5) to (start + 0, 6) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 113, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 23) +- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 43) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 11) = (c0 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: try_error_result::test1 -Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (82): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 4 @@ -63,11 +70,14 @@ Number of expressions: 4 - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Counter(1), rhs = Counter(0) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23) -- Code(Counter(1)) at (prev + 7, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26) -- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 17) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) +- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) +- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) +- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 17) = ((c0 + c2) - c1) - Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42) = ((c0 + c2) - c1) @@ -82,125 +92,157 @@ Number of file 0 mappings: 11 Highest counter ID seen: c2 Function name: try_error_result::test2 -Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 1c, 15, 04, 11, 00, 12, 1e, 02, 11, 03, 27, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 29, 19, 00, 41, 00, 42, 26, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 17, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 29, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 47, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 17, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 29, 29, 00, 42, 00, 43, 66, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 17, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 1d, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 17, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 1d, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 17, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02] +Raw bytes (443): 0x[01, 01, 3d, 0d, 11, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 53, 57, 19, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 09, 8f, 01, 93, 01, 2d, 0d, 29, 09, 0d, 09, 0d, 09, 93, 01, 0d, 29, 09, 8f, 01, 93, 01, 2d, 0d, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 05, 09, c7, 01, 09, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 05, 11, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 0d, 02, 0d, 00, 13, 0d, 00, 14, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs -Number of expressions: 54 +Number of expressions: 61 - expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Expression(15, Add) +- expression 1 operands: lhs = Counter(3), rhs = Expression(21, Add) - expression 2 operands: lhs = Counter(4), rhs = Counter(5) -- expression 3 operands: lhs = Counter(3), rhs = Expression(13, Add) -- expression 4 operands: lhs = Expression(14, Add), rhs = Counter(7) -- expression 5 operands: lhs = Expression(15, Add), rhs = Counter(6) +- expression 3 operands: lhs = Counter(3), rhs = Expression(21, Add) +- expression 4 operands: lhs = Counter(4), rhs = Counter(5) +- expression 5 operands: lhs = Counter(3), rhs = Expression(21, Add) - expression 6 operands: lhs = Counter(4), rhs = Counter(5) -- expression 7 operands: lhs = Counter(3), rhs = Expression(15, Add) -- expression 8 operands: lhs = Counter(4), rhs = Counter(5) -- expression 9 operands: lhs = Counter(3), rhs = Expression(14, Add) -- expression 10 operands: lhs = Expression(15, Add), rhs = Counter(6) -- expression 11 operands: lhs = Counter(4), rhs = Counter(5) -- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add) -- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7) -- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(6) -- expression 15 operands: lhs = Counter(4), rhs = Counter(5) -- expression 16 operands: lhs = Counter(16), rhs = Expression(20, Add) -- expression 17 operands: lhs = Counter(8), rhs = Counter(9) -- expression 18 operands: lhs = Counter(16), rhs = Counter(8) -- expression 19 operands: lhs = Counter(16), rhs = Expression(20, Add) -- expression 20 operands: lhs = Counter(8), rhs = Counter(9) -- expression 21 operands: lhs = Counter(2), rhs = Expression(28, Add) -- expression 22 operands: lhs = Expression(29, Add), rhs = Counter(11) -- expression 23 operands: lhs = Counter(3), rhs = Counter(10) -- expression 24 operands: lhs = Counter(2), rhs = Counter(3) -- expression 25 operands: lhs = Counter(2), rhs = Expression(29, Add) -- expression 26 operands: lhs = Counter(3), rhs = Counter(10) -- expression 27 operands: lhs = Counter(2), rhs = Expression(28, Add) -- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(11) +- expression 7 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 8 operands: lhs = Expression(20, Add), rhs = Counter(7) +- expression 9 operands: lhs = Expression(21, Add), rhs = Counter(6) +- expression 10 operands: lhs = Counter(4), rhs = Counter(5) +- expression 11 operands: lhs = Counter(3), rhs = Expression(21, Add) +- expression 12 operands: lhs = Counter(4), rhs = Counter(5) +- expression 13 operands: lhs = Counter(3), rhs = Expression(21, Add) +- expression 14 operands: lhs = Counter(4), rhs = Counter(5) +- expression 15 operands: lhs = Counter(3), rhs = Expression(20, Add) +- expression 16 operands: lhs = Expression(21, Add), rhs = Counter(6) +- expression 17 operands: lhs = Counter(4), rhs = Counter(5) +- expression 18 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(7) +- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(6) +- expression 21 operands: lhs = Counter(4), rhs = Counter(5) +- expression 22 operands: lhs = Counter(16), rhs = Expression(26, Add) +- expression 23 operands: lhs = Counter(8), rhs = Counter(9) +- expression 24 operands: lhs = Counter(16), rhs = Counter(8) +- expression 25 operands: lhs = Counter(16), rhs = Expression(26, Add) +- expression 26 operands: lhs = Counter(8), rhs = Counter(9) +- expression 27 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 28 operands: lhs = Expression(36, Add), rhs = Counter(11) - expression 29 operands: lhs = Counter(3), rhs = Counter(10) -- expression 30 operands: lhs = Counter(17), rhs = Expression(34, Add) -- expression 31 operands: lhs = Counter(12), rhs = Counter(13) -- expression 32 operands: lhs = Counter(17), rhs = Counter(12) -- expression 33 operands: lhs = Counter(17), rhs = Expression(34, Add) -- expression 34 operands: lhs = Counter(12), rhs = Counter(13) -- expression 35 operands: lhs = Counter(18), rhs = Expression(39, Add) -- expression 36 operands: lhs = Counter(14), rhs = Counter(15) -- expression 37 operands: lhs = Counter(18), rhs = Counter(14) -- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add) -- expression 39 operands: lhs = Counter(14), rhs = Counter(15) -- expression 40 operands: lhs = Counter(1), rhs = Counter(2) -- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(2) -- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(15) -- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(14) -- expression 44 operands: lhs = Expression(45, Add), rhs = Counter(13) -- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(12) -- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(11) -- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(10) -- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(9) -- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(8) -- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(7) -- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(6) -- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(5) -- expression 53 operands: lhs = Counter(1), rhs = Counter(4) -Number of file 0 mappings: 40 -- Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23) -- Code(Counter(1)) at (prev + 8, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26) -- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 31) +- expression 30 operands: lhs = Counter(2), rhs = Counter(3) +- expression 31 operands: lhs = Counter(2), rhs = Counter(3) +- expression 32 operands: lhs = Counter(2), rhs = Expression(36, Add) +- expression 33 operands: lhs = Counter(3), rhs = Counter(10) +- expression 34 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11) +- expression 36 operands: lhs = Counter(3), rhs = Counter(10) +- expression 37 operands: lhs = Counter(17), rhs = Expression(41, Add) +- expression 38 operands: lhs = Counter(12), rhs = Counter(13) +- expression 39 operands: lhs = Counter(17), rhs = Counter(12) +- expression 40 operands: lhs = Counter(17), rhs = Expression(41, Add) +- expression 41 operands: lhs = Counter(12), rhs = Counter(13) +- expression 42 operands: lhs = Counter(18), rhs = Expression(46, Add) +- expression 43 operands: lhs = Counter(14), rhs = Counter(15) +- expression 44 operands: lhs = Counter(18), rhs = Counter(14) +- expression 45 operands: lhs = Counter(18), rhs = Expression(46, Add) +- expression 46 operands: lhs = Counter(14), rhs = Counter(15) +- expression 47 operands: lhs = Counter(1), rhs = Counter(2) +- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(2) +- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(15) +- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(14) +- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(13) +- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(12) +- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(11) +- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(10) +- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(9) +- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(8) +- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(7) +- expression 58 operands: lhs = Expression(59, Add), rhs = Counter(6) +- expression 59 operands: lhs = Expression(60, Add), rhs = Counter(5) +- expression 60 operands: lhs = Counter(1), rhs = Counter(4) +Number of file 0 mappings: 57 +- Code(Counter(0)) at (prev + 61, 1) to (start + 0, 29) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) +- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) +- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) +- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 19) +- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 31) - Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 28) +- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 0, 53) = (c3 - c4) -- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18) -- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 3, 39) +- Code(Expression(0, Sub)) at (prev + 0, 69) to (start + 0, 79) + = (c3 - c4) +- Code(Expression(0, Sub)) at (prev + 0, 80) to (start + 0, 98) + = (c3 - c4) +- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) + = (c3 - c4) +- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 28) + = (c3 - c4) +- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18) +- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 21) = (c3 - (c4 + c5)) -- Code(Expression(12, Sub)) at (prev + 5, 17) to (start + 0, 20) +- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 27) + = (c3 - (c4 + c5)) +- Code(Expression(13, Sub)) at (prev + 1, 21) to (start + 0, 39) + = (c3 - (c4 + c5)) +- Code(Expression(18, Sub)) at (prev + 2, 17) to (start + 0, 20) = (c3 - (((c4 + c5) + c6) + c7)) -- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 41) +- Code(Expression(13, Sub)) at (prev + 0, 23) to (start + 0, 29) + = (c3 - (c4 + c5)) +- Code(Expression(13, Sub)) at (prev + 0, 30) to (start + 0, 41) = (c3 - (c4 + c5)) - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 71) +- Code(Expression(15, Sub)) at (prev + 0, 67) to (start + 0, 71) = (c3 - ((c4 + c5) + c6)) - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) -- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 23) +- Code(Expression(18, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c3 - (((c4 + c5) + c6) + c7)) -- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c16 - (c8 + c9)) -- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 41) +- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 29) +- Code(Counter(16)) at (prev + 0, 30) to (start + 0, 41) - Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 71) +- Code(Expression(24, Sub)) at (prev + 0, 67) to (start + 0, 71) = (c16 - c8) - Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97) -- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 23) +- Code(Expression(25, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c16 - (c8 + c9)) -- Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 20) +- Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 20) = (c2 - ((c3 + c10) + c11)) -- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 41) +- Code(Expression(31, Sub)) at (prev + 0, 23) to (start + 0, 29) + = (c2 - c3) +- Code(Expression(31, Sub)) at (prev + 0, 30) to (start + 0, 41) = (c2 - c3) - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) -- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 72) +- Code(Expression(32, Sub)) at (prev + 0, 68) to (start + 0, 72) = (c2 - (c3 + c10)) - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) -- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 23) +- Code(Expression(34, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c2 - ((c3 + c10) + c11)) -- Code(Expression(33, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c17 - (c12 + c13)) -- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 29) -- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55) -- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 22) +- Code(Counter(17)) at (prev + 0, 23) to (start + 0, 29) +- Code(Counter(17)) at (prev + 1, 18) to (start + 0, 29) +- Code(Counter(12)) at (prev + 0, 54) to (start + 0, 55) +- Code(Expression(39, Sub)) at (prev + 1, 18) to (start + 0, 22) = (c17 - c12) - Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 23) +- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c17 - (c12 + c13)) -- Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c18 - (c14 + c15)) -- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 29) -- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18) -- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 22) +- Code(Counter(18)) at (prev + 0, 23) to (start + 0, 29) +- Code(Counter(18)) at (prev + 1, 18) to (start + 0, 29) +- Code(Counter(14)) at (prev + 1, 17) to (start + 0, 18) +- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 22) = (c18 - c14) - Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18) -- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 23) +- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 23) = (c18 - (c14 + c15)) -- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 11) +- Code(Expression(47, Sub)) at (prev + 3, 5) to (start + 0, 11) = (c1 - c2) -- Code(Expression(41, Sub)) at (prev + 1, 1) to (start + 0, 2) +- Code(Expression(48, Sub)) at (prev + 1, 1) to (start + 0, 2) = (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2) Highest counter ID seen: c18 diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage index 7a89c0452ac4..f2ec82f20fa2 100644 --- a/tests/coverage/try_error_result.coverage +++ b/tests/coverage/try_error_result.coverage @@ -21,8 +21,8 @@ LL| | { LL| 6| countdown LL| 6| -= 1 - LL| 6| ; - LL| 6| if + LL| | ; + LL| | if LL| 6| countdown < 5 LL| | { LL| 1| call(/*return_error=*/ true)?; @@ -71,19 +71,19 @@ LL| | { LL| 6| countdown LL| 6| -= 1 - LL| 6| ; - LL| 6| if + LL| | ; + LL| | if LL| 6| countdown < 5 LL| | { LL| 1| thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail"); ^0 LL| 1| thing1 - LL| 1| . + LL| | . LL| 1| get_thing_2(/*return_error=*/ false) LL| 0| ? LL| | . LL| 1| call(/*return_error=*/ true) - LL| 1| . + LL| | . LL| 1| expect_err( LL| 1| "call should fail" LL| | ); diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map index 7ad4395491f0..bbfa8b940c6d 100644 --- a/tests/coverage/unicode.cov-map +++ b/tests/coverage/unicode.cov-map @@ -1,12 +1,12 @@ Function name: unicode::main -Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02] +Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unicode.rs Number of expressions: 2 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 11) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12) = (c1 - c0) - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27) @@ -17,24 +17,28 @@ Number of file 0 mappings: 9 - Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6) - Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c3) -- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 Function name: unicode::他 (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 1e, 19, 00, 22, 00, 00, 24, 00, 25] Number of files: 1 - file 0 => $DIR/unicode.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 30, 25) to (start + 0, 37) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 30, 25) to (start + 0, 34) +- Code(Zero) at (prev + 0, 36) to (start + 0, 37) Highest counter ID seen: (none) Function name: unicode::申し訳ございません -Raw bytes (9): 0x[01, 01, 00, 01, 01, 18, 01, 02, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 18, 01, 00, 29, 01, 01, 05, 00, 19, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unicode.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2) +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 25) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage index 443499545500..4646cc92e8e4 100644 --- a/tests/coverage/unicode.coverage +++ b/tests/coverage/unicode.coverage @@ -29,7 +29,7 @@ LL| | LL| |macro_rules! macro_that_defines_a_function { LL| | (fn $名:ident () $体:tt) => { - LL| 0| fn $名 () $体 fn 他 () {} + LL| 0| fn $名 () $体 fn 他 () {} LL| | } LL| |} LL| | diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map index fd9a1abc8cb0..c38786ee664c 100644 --- a/tests/coverage/unreachable.cov-map +++ b/tests/coverage/unreachable.cov-map @@ -1,27 +1,29 @@ Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 45] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 30, 00, 45] Number of files: 1 - file 0 => $DIR/unreachable.rs Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 14, 39) to (start + 0, 69) +- Code(Zero) at (prev + 14, 48) to (start + 0, 69) Highest counter ID seen: (none) Function name: unreachable::unreachable_function (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 23] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 10, 01, 00, 1a, 00, 01, 0e, 00, 23] Number of files: 1 - file 0 => $DIR/unreachable.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 16, 1) to (start + 1, 35) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 16, 1) to (start + 0, 26) +- Code(Zero) at (prev + 1, 14) to (start + 0, 35) Highest counter ID seen: (none) Function name: unreachable::unreachable_intrinsic (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2a] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 01, 00, 1b, 00, 01, 0e, 00, 2a] Number of files: 1 - file 0 => $DIR/unreachable.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 1) to (start + 1, 42) +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 21, 1) to (start + 0, 27) +- Code(Zero) at (prev + 1, 14) to (start + 0, 42) Highest counter ID seen: (none) diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map index 8946b43a8bbc..3380997b921e 100644 --- a/tests/coverage/unused.cov-map +++ b/tests/coverage/unused.cov-map @@ -1,14 +1,16 @@ Function name: unused::foo:: -Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] +Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15) = (c1 - c0) - Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25) @@ -19,16 +21,18 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: unused::foo:: -Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] +Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Counter(0) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14) +- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15) = (c1 - c0) - Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25) @@ -39,58 +43,67 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: unused::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 04, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: unused::unused_func (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 13, 01, 00, 1b, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Zero) at (prev + 19, 1) to (start + 1, 14) -- Code(Zero) at (prev + 1, 15) to (start + 2, 6) +Number of file 0 mappings: 5 +- Code(Zero) at (prev + 19, 1) to (start + 0, 27) +- Code(Zero) at (prev + 1, 8) to (start + 0, 14) +- Code(Zero) at (prev + 0, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: unused::unused_func2 (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 19, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Zero) at (prev + 25, 1) to (start + 1, 14) -- Code(Zero) at (prev + 1, 15) to (start + 2, 6) +Number of file 0 mappings: 5 +- Code(Zero) at (prev + 25, 1) to (start + 0, 28) +- Code(Zero) at (prev + 1, 8) to (start + 0, 14) +- Code(Zero) at (prev + 0, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: unused::unused_func3 (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 1f, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Zero) at (prev + 31, 1) to (start + 1, 14) -- Code(Zero) at (prev + 1, 15) to (start + 2, 6) +Number of file 0 mappings: 5 +- Code(Zero) at (prev + 31, 1) to (start + 0, 28) +- Code(Zero) at (prev + 1, 8) to (start + 0, 14) +- Code(Zero) at (prev + 0, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) Function name: unused::unused_template_func::<_> (unused) -Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 00, 0b, 01, 00, 21, 00, 01, 09, 00, 0e, 00, 00, 11, 00, 12, 00, 01, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused.rs Number of expressions: 0 -Number of file 0 mappings: 6 -- Code(Zero) at (prev + 11, 1) to (start + 1, 18) -- Code(Zero) at (prev + 2, 11) to (start + 0, 17) +Number of file 0 mappings: 8 +- Code(Zero) at (prev + 11, 1) to (start + 0, 33) +- Code(Zero) at (prev + 1, 9) to (start + 0, 14) +- Code(Zero) at (prev + 0, 17) to (start + 0, 18) +- Code(Zero) at (prev + 1, 11) to (start + 0, 17) - Code(Zero) at (prev + 1, 9) to (start + 0, 15) - Code(Zero) at (prev + 0, 19) to (start + 0, 25) - Code(Zero) at (prev + 1, 9) to (start + 0, 15) diff --git a/tests/coverage/unused_mod.cov-map b/tests/coverage/unused_mod.cov-map index 790cd701dc3a..ea419edbdafe 100644 --- a/tests/coverage/unused_mod.cov-map +++ b/tests/coverage/unused_mod.cov-map @@ -1,18 +1,24 @@ Function name: unused_mod::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 1c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unused_mod.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: unused_mod::unused_module::never_called_function (unused) -Raw bytes (9): 0x[01, 02, 00, 01, 00, 02, 01, 02, 02] +Raw bytes (24): 0x[01, 02, 00, 04, 00, 02, 01, 00, 1f, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 21, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/unused_mod_helper.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Zero) at (prev + 2, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Zero) at (prev + 2, 1) to (start + 0, 31) +- Code(Zero) at (prev + 1, 5) to (start + 0, 13) +- Code(Zero) at (prev + 0, 14) to (start + 0, 33) +- Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: (none) diff --git a/tests/coverage/uses_crate.cov-map b/tests/coverage/uses_crate.cov-map index 238226f3d683..8f3c63aba5ce 100644 --- a/tests/coverage/uses_crate.cov-map +++ b/tests/coverage/uses_crate.cov-map @@ -1,45 +1,67 @@ Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 1b, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 76) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_crate::used_only_from_bin_crate_generic_function::<&str> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 91) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: uses_crate::main -Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02] +Raw bytes (59): 0x[01, 02, 00, 0b, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 1e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 3a, 01, 00, 3b, 00, 44, 01, 01, 05, 00, 3a, 01, 01, 05, 00, 43, 01, 00, 44, 00, 4c, 01, 01, 05, 00, 52, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/uses_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 30) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58) +- Code(Counter(0)) at (prev + 0, 59) to (start + 0, 68) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67) +- Code(Counter(0)) at (prev + 0, 68) to (start + 0, 76) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 82) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/uses_crate.coverage b/tests/coverage/uses_crate.coverage index d1b0dadda768..145c0649ac7b 100644 --- a/tests/coverage/uses_crate.coverage +++ b/tests/coverage/uses_crate.coverage @@ -6,9 +6,9 @@ $DIR/auxiliary/used_crate.rs: LL| |use std::fmt::Debug; LL| | LL| 1|pub fn used_function() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; LL| 1| let mut countdown = 0; LL| 1| if is_true { @@ -104,8 +104,8 @@ $DIR/auxiliary/used_crate.rs: LL| 1|fn use_this_lib_crate() { LL| 1| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); LL| 1| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - LL| 1| "used from library used_crate.rs", - LL| 1| ); + LL| | "used from library used_crate.rs", + LL| | ); LL| 1| let some_vec = vec![5, 6, 7, 8]; LL| 1| used_only_from_this_lib_crate_generic_function(some_vec); LL| 1| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); diff --git a/tests/coverage/uses_inline_crate.cov-map b/tests/coverage/uses_inline_crate.cov-map index fd14ea341202..52f3f94ce642 100644 --- a/tests/coverage/uses_inline_crate.cov-map +++ b/tests/coverage/uses_inline_crate.cov-map @@ -1,59 +1,88 @@ Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 2c, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 76) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_inline_crate::used_inline_function -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 01, 02] +Raw bytes (56): 0x[01, 01, 01, 01, 05, 0a, 01, 14, 01, 00, 1e, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 17, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 20, 1) to (start + 6, 15) -- Code(Counter(1)) at (prev + 6, 16) to (start + 2, 6) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 20, 1) to (start + 0, 30) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) +- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 31, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/auxiliary/used_inline_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 91) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: uses_inline_crate::main -Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02] +Raw bytes (64): 0x[01, 02, 00, 0c, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 25, 01, 01, 05, 00, 2c, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 41, 01, 00, 42, 00, 4b, 01, 01, 05, 00, 41, 01, 01, 05, 00, 4a, 01, 00, 4b, 00, 53, 01, 01, 05, 00, 59, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/uses_inline_crate.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 37) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 44) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65) +- Code(Counter(0)) at (prev + 0, 66) to (start + 0, 75) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 74) +- Code(Counter(0)) at (prev + 0, 75) to (start + 0, 83) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 89) +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/uses_inline_crate.coverage b/tests/coverage/uses_inline_crate.coverage index 4671c95aefa4..15084bcf7ea9 100644 --- a/tests/coverage/uses_inline_crate.coverage +++ b/tests/coverage/uses_inline_crate.coverage @@ -6,9 +6,9 @@ $DIR/auxiliary/used_inline_crate.rs: LL| |use std::fmt::Debug; LL| | LL| 1|pub fn used_function() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; LL| 1| let mut countdown = 0; LL| 1| if is_true { @@ -20,9 +20,9 @@ $DIR/auxiliary/used_inline_crate.rs: LL| | LL| |#[inline(always)] LL| 1|pub fn used_inline_function() { - LL| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure - LL| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - LL| 1| // dependent conditions. + LL| | // Initialize test constants in a way that cannot be determined at compile time, to ensure + LL| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + LL| | // dependent conditions. LL| 1| let is_true = std::env::args().len() == 1; LL| 1| let mut countdown = 0; LL| 1| if is_true { @@ -126,8 +126,8 @@ $DIR/auxiliary/used_inline_crate.rs: LL| 2|fn use_this_lib_crate() { LL| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); LL| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - LL| 2| "used from library used_crate.rs", - LL| 2| ); + LL| | "used from library used_crate.rs", + LL| | ); LL| 2| let some_vec = vec![5, 6, 7, 8]; LL| 2| used_only_from_this_lib_crate_generic_function(some_vec); LL| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); @@ -153,7 +153,7 @@ $DIR/uses_inline_crate.rs: LL| 1| used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs"); LL| 1| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec); LL| 1| used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - LL| 1| "interesting?", - LL| 1| ); + LL| | "interesting?", + LL| | ); LL| 1|} diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map index 8ad739206297..c4183e18e021 100644 --- a/tests/coverage/while.cov-map +++ b/tests/coverage/while.cov-map @@ -1,11 +1,13 @@ Function name: while::main -Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 01, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 10, 01, 01, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while.rs Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16) -- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 20) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) +- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 20) - Code(Zero) at (prev + 0, 21) to (start + 2, 6) - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map index 6e3db66f97c7..b29b5d40c4df 100644 --- a/tests/coverage/while_early_ret.cov-map +++ b/tests/coverage/while_early_ret.cov-map @@ -1,27 +1,32 @@ Function name: while_early_ret::main -Raw bytes (63): 0x[01, 01, 07, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 09, 09, 01, 05, 01, 01, 1b, 05, 03, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 16, 03, 0a, 03, 0a, 1a, 06, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (80): 0x[01, 01, 08, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 01, 05, 09, 0c, 01, 05, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 1a, 03, 09, 00, 0a, 1a, 01, 09, 02, 0a, 1e, 05, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/while_early_ret.rs -Number of expressions: 7 +Number of expressions: 8 - expression 0 operands: lhs = Expression(3, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add) - expression 3 operands: lhs = Counter(0), rhs = Counter(2) - expression 4 operands: lhs = Counter(1), rhs = Counter(3) - expression 5 operands: lhs = Counter(1), rhs = Counter(0) -- expression 6 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 27) -- Code(Counter(1)) at (prev + 3, 9) to (start + 2, 10) +- expression 6 operands: lhs = Counter(1), rhs = Counter(0) +- expression 7 operands: lhs = Counter(1), rhs = Counter(2) +Number of file 0 mappings: 12 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 28) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27) +- Code(Counter(1)) at (prev + 2, 9) to (start + 2, 10) - Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14) - Code(Expression(0, Sub)) at (prev + 6, 21) to (start + 2, 22) = ((c0 + c2) - c1) - Code(Counter(3)) at (prev + 4, 21) to (start + 0, 27) - Code(Expression(2, Sub)) at (prev + 4, 21) to (start + 0, 27) = ((c0 + c2) - (c1 + c3)) -- Code(Expression(5, Sub)) at (prev + 3, 10) to (start + 3, 10) +- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 10) = (c1 - c0) -- Code(Expression(6, Sub)) at (prev + 6, 5) to (start + 0, 11) +- Code(Expression(6, Sub)) at (prev + 1, 9) to (start + 2, 10) + = (c1 - c0) +- Code(Expression(7, Sub)) at (prev + 5, 5) to (start + 0, 11) = (c1 - c2) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c3 diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map index db82c9d673d1..87d0a0472615 100644 --- a/tests/coverage/yield.cov-map +++ b/tests/coverage/yield.cov-map @@ -1,5 +1,5 @@ Function name: yield::main -Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02] +Raw bytes (139): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 19, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 0b, 00, 2e, 01, 00, 14, 00, 22, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 13, 09, 00, 0b, 00, 2e, 09, 00, 14, 00, 22, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 13, 11, 00, 0b, 00, 2e, 11, 00, 14, 00, 22, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/yield.rs Number of expressions: 5 @@ -8,23 +8,32 @@ Number of expressions: 5 - expression 2 operands: lhs = Counter(2), rhs = Counter(4) - expression 3 operands: lhs = Counter(4), rhs = Counter(5) - expression 4 operands: lhs = Counter(4), rhs = Counter(5) -Number of file 0 mappings: 16 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22) -- Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46) +Number of file 0 mappings: 25 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) +- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 11) to (start + 0, 46) +- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34) - Code(Counter(1)) at (prev + 1, 39) to (start + 0, 41) - Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20) = (c0 - c1) -- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46) +- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19) +- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46) +- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34) - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39) - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46) - Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20) = (c1 - c2) - Code(Counter(2)) at (prev + 3, 9) to (start + 0, 22) -- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 46) +- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 19) +- Code(Counter(2)) at (prev + 0, 11) to (start + 0, 46) +- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 34) - Code(Counter(4)) at (prev + 1, 39) to (start + 0, 41) - Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 20) = (c2 - c4) -- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46) +- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 19) +- Code(Counter(4)) at (prev + 0, 11) to (start + 0, 46) +- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 34) - Code(Expression(4, Sub)) at (prev + 1, 39) to (start + 0, 41) = (c4 - c5) - Code(Counter(5)) at (prev + 1, 14) to (start + 0, 20) @@ -33,24 +42,28 @@ Number of file 0 mappings: 16 Highest counter ID seen: c5 Function name: yield::main::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 09, 08, 01, 10, 05, 02, 10, 01, 06] -Number of files: 1 -- file 0 => $DIR/yield.rs -Number of expressions: 0 -Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 9, 8) to (start + 1, 16) -- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6) -Highest counter ID seen: c1 - -Function name: yield::main::{closure#1} -Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 08, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/yield.rs Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 24, 8) to (start + 1, 16) -- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 9, 8) to (start + 0, 9) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c1 + +Function name: yield::main::{closure#1} +Raw bytes (34): 0x[01, 01, 00, 06, 01, 18, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 00, 15, 0d, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/yield.rs +Number of expressions: 0 +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 24, 8) to (start + 0, 9) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 16) -- Code(Counter(3)) at (prev + 1, 16) to (start + 1, 6) +- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 21) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 6) Highest counter ID seen: c3 diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index 542b70bcee96..d465b8bded22 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -26,11 +26,20 @@ debug a => _9; } -+ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0); -+ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:32 (#0); -+ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:32 (#0); -+ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:32 (#0); -+ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:32 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 14:10 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:15:11: 15:21 (#0); ++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:18 (#0); ++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:23: 16:30 (#0); ++ coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:31: 16:32 (#0); ++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:18 (#0); ++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:23: 17:30 (#0); ++ coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:31: 17:32 (#0); ++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:18 (#0); ++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:23: 18:30 (#0); ++ coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:31: 18:32 (#0); ++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:18 (#0); ++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:23: 19:30 (#0); ++ coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:31: 19:32 (#0); + coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0); + bb0: { diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff index 06e5f011c761..cf6d85abd80e 100644 --- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff @@ -4,7 +4,9 @@ fn bar() -> bool { let mut _0: bool; -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 29:2 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 27:17 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:28:5: 28:9 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:2: 29:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff index 30de92f3b868..980c5e202ffd 100644 --- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff @@ -7,7 +7,7 @@ let mut _2: bool; let mut _3: !; -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:11 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:10 (#0); + coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:15 (#0); + coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0); + coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#0); diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff index 1a22adeba6fc..b707cd41788a 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff @@ -7,7 +7,8 @@ coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0) - coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0); + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0); + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0); diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff index b77969a3e169..239b845c2311 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff @@ -7,7 +7,8 @@ coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0) -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); + coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); + coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); + coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0); From 77a7ae4e9fcbf3be3988c98015d7f52137bb237c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 17 Apr 2025 17:03:08 +1000 Subject: [PATCH 191/262] coverage: Handle hole spans without dividing spans into buckets Because we no longer merge non-adjacent spans, there is no need to use buckets to prevent merging across hole spans. --- .../rustc_mir_transform/src/coverage/spans.rs | 90 +++++++------------ 1 file changed, 32 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index e6e7e2920ec0..ec76076020eb 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,11 +1,8 @@ -use std::collections::VecDeque; -use std::iter; - use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir; use rustc_middle::ty::TyCtxt; use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span}; -use tracing::{debug, debug_span, instrument}; +use tracing::instrument; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir}; @@ -83,24 +80,17 @@ pub(super) fn extract_refined_covspans<'tcx>( holes.sort_by(|a, b| compare_spans(a.span, b.span)); holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b)); - // Split the covspans into separate buckets that don't overlap any holes. - let buckets = divide_spans_into_buckets(covspans, &holes); + // Discard any span that overlaps with a hole. + discard_spans_overlapping_holes(&mut covspans, &holes); - for covspans in buckets { - let _span = debug_span!("processing bucket", ?covspans).entered(); + // Perform more refinement steps after holes have been dealt with. + let mut covspans = remove_unwanted_overlapping_spans(covspans); + covspans.dedup_by(|b, a| a.merge_if_eligible(b)); - let mut covspans = remove_unwanted_overlapping_spans(covspans); - debug!(?covspans, "after removing overlaps"); - - // Do one last merge pass, to simplify the output. - covspans.dedup_by(|b, a| a.merge_if_eligible(b)); - debug!(?covspans, "after merge"); - - code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| { - // Each span produced by the refiner represents an ordinary code region. - mappings::CodeMapping { span, bcb } - })); - } + code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| { + // Each span produced by the refiner represents an ordinary code region. + mappings::CodeMapping { span, bcb } + })); } /// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate @@ -142,52 +132,36 @@ fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec) } } -/// Uses the holes to divide the given covspans into buckets, such that: -/// - No span in any hole overlaps a bucket (discarding spans if necessary). -/// - The spans in each bucket are strictly after all spans in previous buckets, -/// and strictly before all spans in subsequent buckets. +/// Discard all covspans that overlap a hole. /// -/// The lists of covspans and holes must be sorted. -/// The resulting buckets are sorted relative to each other, and each bucket's -/// contents are sorted. -#[instrument(level = "debug")] -fn divide_spans_into_buckets(input_covspans: Vec, holes: &[Hole]) -> Vec> { - debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le())); +/// The lists of covspans and holes must be sorted, and any holes that overlap +/// with each other must have already been merged. +fn discard_spans_overlapping_holes(covspans: &mut Vec, holes: &[Hole]) { + debug_assert!(covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le())); debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le())); + debug_assert!(holes.array_windows().all(|[a, b]| !a.span.overlaps_or_adjacent(b.span))); - // Now we're ready to start grouping spans into buckets separated by holes. + let mut curr_hole = 0usize; + let mut overlaps_hole = |covspan: &Covspan| -> bool { + while let Some(hole) = holes.get(curr_hole) { + // Both lists are sorted, so we can permanently skip any holes that + // end before the start of the current span. + if hole.span.hi() <= covspan.span.lo() { + curr_hole += 1; + continue; + } - let mut input_covspans = VecDeque::from(input_covspans); + return hole.span.overlaps(covspan.span); + } - // For each hole: - // - Identify the spans that are entirely or partly before the hole. - // - Discard any that overlap with the hole. - // - Add the remaining identified spans to the corresponding bucket. - let mut buckets = (0..holes.len()).map(|_| vec![]).collect::>(); - for (hole, bucket) in holes.iter().zip(&mut buckets) { - bucket.extend( - drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi()) - .filter(|c| !c.span.overlaps(hole.span)), - ); - } + // No holes left, so this covspan doesn't overlap with any holes. + false + }; - // Any remaining spans form their own final bucket, after the final hole. - // (If there were no holes, this will just be all of the initial spans.) - buckets.push(Vec::from(input_covspans)); - - buckets + covspans.retain(|covspan| !overlaps_hole(covspan)); } -/// Similar to `.drain(..)`, but stops just before it would remove an item not -/// satisfying the predicate. -fn drain_front_while<'a, T>( - queue: &'a mut VecDeque, - mut pred_fn: impl FnMut(&T) -> bool, -) -> impl Iterator { - iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x))) -} - -/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines" +/// Takes a list of sorted spans extracted from MIR, and "refines" /// those spans by removing spans that overlap in unwanted ways. #[instrument(level = "debug")] fn remove_unwanted_overlapping_spans(sorted_spans: Vec) -> Vec { From 18a3599fe35a7df3ac5be1778d91f59c6b17d309 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 28 Jan 2025 13:38:30 +0100 Subject: [PATCH 192/262] Update iterator.rs to use arrays by value Update examples to no longer avoid iterating arrays for #84513 --- library/core/src/iter/traits/iterator.rs | 455 +++++++++++------------ 1 file changed, 225 insertions(+), 230 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 91c3a4b29b53..24d1d060f9ad 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -56,12 +56,12 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// /// // A call to next() returns the next value... - /// assert_eq!(Some(&1), iter.next()); - /// assert_eq!(Some(&2), iter.next()); - /// assert_eq!(Some(&3), iter.next()); + /// assert_eq!(Some(1), iter.next()); + /// assert_eq!(Some(2), iter.next()); + /// assert_eq!(Some(3), iter.next()); /// /// // ... and then None once it's over. /// assert_eq!(None, iter.next()); @@ -239,10 +239,10 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().last(), Some(&3)); + /// assert_eq!(a.into_iter().last(), Some(3)); /// /// let a = [1, 2, 3, 4, 5]; - /// assert_eq!(a.iter().last(), Some(&5)); + /// assert_eq!(a.into_iter().last(), Some(5)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -284,12 +284,12 @@ pub trait Iterator { /// use std::num::NonZero; /// /// let a = [1, 2, 3, 4]; - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// /// assert_eq!(iter.advance_by(2), Ok(())); - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// assert_eq!(iter.advance_by(0), Ok(())); - /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `&4` was skipped + /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `4` was skipped /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] @@ -322,7 +322,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth(1), Some(&2)); + /// assert_eq!(a.into_iter().nth(1), Some(2)); /// ``` /// /// Calling `nth()` multiple times doesn't rewind the iterator: @@ -330,9 +330,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert_eq!(iter.nth(1), Some(&2)); + /// assert_eq!(iter.nth(1), Some(2)); /// assert_eq!(iter.nth(1), None); /// ``` /// @@ -340,7 +340,7 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth(10), None); + /// assert_eq!(a.into_iter().nth(10), None); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -385,11 +385,11 @@ pub trait Iterator { /// /// ``` /// let a = [0, 1, 2, 3, 4, 5]; - /// let mut iter = a.iter().step_by(2); + /// let mut iter = a.into_iter().step_by(2); /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(4)); /// assert_eq!(iter.next(), None); /// ``` #[inline] @@ -417,37 +417,37 @@ pub trait Iterator { /// Basic usage: /// /// ``` - /// let a1 = [1, 2, 3]; - /// let a2 = [4, 5, 6]; + /// let s1 = "abc".chars(); + /// let s2 = "def".chars(); /// - /// let mut iter = a1.iter().chain(a2.iter()); + /// let mut iter = s1.chain(s2); /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&4)); - /// assert_eq!(iter.next(), Some(&5)); - /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), Some('a')); + /// assert_eq!(iter.next(), Some('b')); + /// assert_eq!(iter.next(), Some('c')); + /// assert_eq!(iter.next(), Some('d')); + /// assert_eq!(iter.next(), Some('e')); + /// assert_eq!(iter.next(), Some('f')); /// assert_eq!(iter.next(), None); /// ``` /// /// Since the argument to `chain()` uses [`IntoIterator`], we can pass /// anything that can be converted into an [`Iterator`], not just an - /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`Iterator`] itself. For example, arrays (`[T]`) implement /// [`IntoIterator`], and so can be passed to `chain()` directly: /// /// ``` - /// let s1 = &[1, 2, 3]; - /// let s2 = &[4, 5, 6]; + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; /// - /// let mut iter = s1.iter().chain(s2); + /// let mut iter = a1.into_iter().chain(a2); /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&4)); - /// assert_eq!(iter.next(), Some(&5)); - /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(3)); + /// assert_eq!(iter.next(), Some(4)); + /// assert_eq!(iter.next(), Some(5)); + /// assert_eq!(iter.next(), Some(6)); /// assert_eq!(iter.next(), None); /// ``` /// @@ -496,31 +496,31 @@ pub trait Iterator { /// Basic usage: /// /// ``` - /// let a1 = [1, 2, 3]; - /// let a2 = [4, 5, 6]; + /// let s1 = "abc".chars(); + /// let s2 = "def".chars(); /// - /// let mut iter = a1.iter().zip(a2.iter()); + /// let mut iter = s1.zip(s2); /// - /// assert_eq!(iter.next(), Some((&1, &4))); - /// assert_eq!(iter.next(), Some((&2, &5))); - /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), Some(('a', 'd'))); + /// assert_eq!(iter.next(), Some(('b', 'e'))); + /// assert_eq!(iter.next(), Some(('c', 'f'))); /// assert_eq!(iter.next(), None); /// ``` /// /// Since the argument to `zip()` uses [`IntoIterator`], we can pass /// anything that can be converted into an [`Iterator`], not just an - /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`Iterator`] itself. For example, arrays (`[T]`) implement /// [`IntoIterator`], and so can be passed to `zip()` directly: /// /// ``` - /// let s1 = &[1, 2, 3]; - /// let s2 = &[4, 5, 6]; + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; /// - /// let mut iter = s1.iter().zip(s2); + /// let mut iter = a1.into_iter().zip(a2); /// - /// assert_eq!(iter.next(), Some((&1, &4))); - /// assert_eq!(iter.next(), Some((&2, &5))); - /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), Some((1, 4))); + /// assert_eq!(iter.next(), Some((2, 5))); + /// assert_eq!(iter.next(), Some((3, 6))); /// assert_eq!(iter.next(), None); /// ``` /// @@ -604,12 +604,12 @@ pub trait Iterator { /// ``` /// #![feature(iter_intersperse)] /// - /// let mut a = [0, 1, 2].iter().intersperse(&100); - /// assert_eq!(a.next(), Some(&0)); // The first element from `a`. - /// assert_eq!(a.next(), Some(&100)); // The separator. - /// assert_eq!(a.next(), Some(&1)); // The next element from `a`. - /// assert_eq!(a.next(), Some(&100)); // The separator. - /// assert_eq!(a.next(), Some(&2)); // The last element from `a`. + /// let mut a = [0, 1, 2].into_iter().intersperse(100); + /// assert_eq!(a.next(), Some(0)); // The first element from `a`. + /// assert_eq!(a.next(), Some(100)); // The separator. + /// assert_eq!(a.next(), Some(1)); // The next element from `a`. + /// assert_eq!(a.next(), Some(100)); // The separator. + /// assert_eq!(a.next(), Some(2)); // The last element from `a`. /// assert_eq!(a.next(), None); // The iterator is finished. /// ``` /// @@ -617,7 +617,8 @@ pub trait Iterator { /// ``` /// #![feature(iter_intersperse)] /// - /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::(); + /// let words = ["Hello", "World", "!"]; + /// let hello: String = words.into_iter().intersperse(" ").collect(); /// assert_eq!(hello, "Hello World !"); /// ``` /// @@ -673,7 +674,7 @@ pub trait Iterator { /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied(); /// /// // The closure mutably borrows its context to generate an item. - /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied(); + /// let mut happy_emojis = [" ❤️ ", " 😀 "].into_iter(); /// let separator = || happy_emojis.next().unwrap_or(" 🦀 "); /// /// let result = src.intersperse_with(separator).collect::(); @@ -734,7 +735,7 @@ pub trait Iterator { /// /// // it won't even execute, as it is lazy. Rust will warn you about this. /// - /// // Instead, use for: + /// // Instead, use a for-loop: /// for x in 0..5 { /// println!("{x}"); /// } @@ -814,10 +815,10 @@ pub trait Iterator { /// ``` /// let a = [0i32, 1, 2]; /// - /// let mut iter = a.iter().filter(|x| x.is_positive()); + /// let mut iter = a.into_iter().filter(|x| x.is_positive()); /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` /// @@ -826,21 +827,20 @@ pub trait Iterator { /// situation, where the type of the closure is a double reference: /// /// ``` - /// let a = [0, 1, 2]; + /// let s = &[0, 1, 2]; /// - /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s! + /// let mut iter = s.iter().filter(|x| **x > 1); // needs two *s! /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); /// ``` /// - /// It's common to instead use destructuring on the argument to strip away - /// one: + /// It's common to instead use destructuring on the argument to strip away one: /// /// ``` - /// let a = [0, 1, 2]; + /// let s = &[0, 1, 2]; /// - /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and * + /// let mut iter = s.iter().filter(|&x| *x > 1); // both & and * /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); @@ -849,9 +849,9 @@ pub trait Iterator { /// or both: /// /// ``` - /// let a = [0, 1, 2]; + /// let s = &[0, 1, 2]; /// - /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s + /// let mut iter = s.iter().filter(|&&x| x > 1); // two &s /// /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); @@ -945,11 +945,11 @@ pub trait Iterator { /// ``` /// let a = ['a', 'b', 'c']; /// - /// let mut iter = a.iter().enumerate(); + /// let mut iter = a.into_iter().enumerate(); /// - /// assert_eq!(iter.next(), Some((0, &'a'))); - /// assert_eq!(iter.next(), Some((1, &'b'))); - /// assert_eq!(iter.next(), Some((2, &'c'))); + /// assert_eq!(iter.next(), Some((0, 'a'))); + /// assert_eq!(iter.next(), Some((1, 'b'))); + /// assert_eq!(iter.next(), Some((2, 'c'))); /// assert_eq!(iter.next(), None); /// ``` #[inline] @@ -980,19 +980,19 @@ pub trait Iterator { /// ``` /// let xs = [1, 2, 3]; /// - /// let mut iter = xs.iter().peekable(); + /// let mut iter = xs.into_iter().peekable(); /// /// // peek() lets us see into the future - /// assert_eq!(iter.peek(), Some(&&1)); - /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.peek(), Some(&1)); + /// assert_eq!(iter.next(), Some(1)); /// - /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(2)); /// /// // we can peek() multiple times, the iterator won't advance - /// assert_eq!(iter.peek(), Some(&&3)); - /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&3)); + /// assert_eq!(iter.peek(), Some(&3)); /// - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// /// // after the iterator is finished, so is peek() /// assert_eq!(iter.peek(), None); @@ -1005,21 +1005,21 @@ pub trait Iterator { /// ``` /// let xs = [1, 2, 3]; /// - /// let mut iter = xs.iter().peekable(); + /// let mut iter = xs.into_iter().peekable(); /// /// // `peek_mut()` lets us see into the future - /// assert_eq!(iter.peek_mut(), Some(&mut &1)); - /// assert_eq!(iter.peek_mut(), Some(&mut &1)); - /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.peek_mut(), Some(&mut 1)); + /// assert_eq!(iter.peek_mut(), Some(&mut 1)); + /// assert_eq!(iter.next(), Some(1)); /// - /// if let Some(mut p) = iter.peek_mut() { - /// assert_eq!(*p, &2); + /// if let Some(p) = iter.peek_mut() { + /// assert_eq!(*p, 2); /// // put a value into the iterator - /// *p = &1000; + /// *p = 1000; /// } /// /// // The value reappears as the iterator continues - /// assert_eq!(iter.collect::>(), vec![&1000, &3]); + /// assert_eq!(iter.collect::>(), vec![1000, 3]); /// ``` /// [`peek`]: Peekable::peek /// [`peek_mut`]: Peekable::peek_mut @@ -1051,10 +1051,10 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 0, 1]; /// - /// let mut iter = a.iter().skip_while(|x| x.is_negative()); + /// let mut iter = a.into_iter().skip_while(|x| x.is_negative()); /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), None); /// ``` /// @@ -1063,9 +1063,9 @@ pub trait Iterator { /// situation, where the type of the closure argument is a double reference: /// /// ``` - /// let a = [-1, 0, 1]; + /// let s = &[-1, 0, 1]; /// - /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s! + /// let mut iter = s.iter().skip_while(|x| **x < 0); // need two *s! /// /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&1)); @@ -1077,14 +1077,14 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1, -2]; /// - /// let mut iter = a.iter().skip_while(|x| **x < 0); + /// let mut iter = a.into_iter().skip_while(|&x| x < 0); /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), Some(1)); /// /// // while this would have been false, since we already got a false, /// // skip_while() isn't used any more - /// assert_eq!(iter.next(), Some(&-2)); + /// assert_eq!(iter.next(), Some(-2)); /// /// assert_eq!(iter.next(), None); /// ``` @@ -1115,9 +1115,9 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 0, 1]; /// - /// let mut iter = a.iter().take_while(|x| x.is_negative()); + /// let mut iter = a.into_iter().take_while(|x| x.is_negative()); /// - /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), Some(-1)); /// assert_eq!(iter.next(), None); /// ``` /// @@ -1126,9 +1126,9 @@ pub trait Iterator { /// situation, where the type of the closure is a double reference: /// /// ``` - /// let a = [-1, 0, 1]; + /// let s = &[-1, 0, 1]; /// - /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s! + /// let mut iter = s.iter().take_while(|x| **x < 0); // need two *s! /// /// assert_eq!(iter.next(), Some(&-1)); /// assert_eq!(iter.next(), None); @@ -1139,12 +1139,12 @@ pub trait Iterator { /// ``` /// let a = [-1, 0, 1, -2]; /// - /// let mut iter = a.iter().take_while(|x| **x < 0); + /// let mut iter = a.into_iter().take_while(|&x| x < 0); /// - /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), Some(-1)); /// /// // We have more elements that are less than zero, but since we already - /// // got a false, take_while() isn't used any more + /// // got a false, take_while() ignores the remaining elements. /// assert_eq!(iter.next(), None); /// ``` /// @@ -1154,18 +1154,15 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3, 4]; - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// let result: Vec = iter.by_ref() - /// .take_while(|n| **n != 3) - /// .cloned() - /// .collect(); + /// let result: Vec = iter.by_ref().take_while(|&n| n != 3).collect(); /// - /// assert_eq!(result, &[1, 2]); + /// assert_eq!(result, [1, 2]); /// - /// let result: Vec = iter.cloned().collect(); + /// let result: Vec = iter.collect(); /// - /// assert_eq!(result, &[4]); + /// assert_eq!(result, [4]); /// ``` /// /// The `3` is no longer there, because it was consumed in order to see if @@ -1193,7 +1190,7 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 4, 0, 1]; /// - /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x)); + /// let mut iter = a.into_iter().map_while(|x| 16i32.checked_div(x)); /// /// assert_eq!(iter.next(), Some(-16)); /// assert_eq!(iter.next(), Some(4)); @@ -1208,8 +1205,8 @@ pub trait Iterator { /// ``` /// let a = [-1i32, 4, 0, 1]; /// - /// let mut iter = a.iter() - /// .map(|x| 16i32.checked_div(*x)) + /// let mut iter = a.into_iter() + /// .map(|x| 16i32.checked_div(x)) /// .take_while(|x| x.is_some()) /// .map(|x| x.unwrap()); /// @@ -1223,12 +1220,12 @@ pub trait Iterator { /// ``` /// let a = [0, 1, 2, -3, 4, 5, -6]; /// - /// let iter = a.iter().map_while(|x| u32::try_from(*x).ok()); - /// let vec = iter.collect::>(); + /// let iter = a.into_iter().map_while(|x| u32::try_from(x).ok()); + /// let vec: Vec<_> = iter.collect(); /// - /// // We have more elements which could fit in u32 (4, 5), but `map_while` returned `None` for `-3` + /// // We have more elements that could fit in u32 (such as 4, 5), but `map_while` returned `None` for `-3` /// // (as the `predicate` returned `None`) and `collect` stops at the first `None` encountered. - /// assert_eq!(vec, vec![0, 1, 2]); + /// assert_eq!(vec, [0, 1, 2]); /// ``` /// /// Because `map_while()` needs to look at the value in order to see if it @@ -1237,17 +1234,17 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, -3, 4]; - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// /// let result: Vec = iter.by_ref() - /// .map_while(|n| u32::try_from(*n).ok()) + /// .map_while(|n| u32::try_from(n).ok()) /// .collect(); /// - /// assert_eq!(result, &[1, 2]); + /// assert_eq!(result, [1, 2]); /// - /// let result: Vec = iter.cloned().collect(); + /// let result: Vec = iter.collect(); /// - /// assert_eq!(result, &[4]); + /// assert_eq!(result, [4]); /// ``` /// /// The `-3` is no longer there, because it was consumed in order to see if @@ -1255,7 +1252,7 @@ pub trait Iterator { /// /// Note that unlike [`take_while`] this iterator is **not** fused. /// It is also not specified what this iterator returns after the first [`None`] is returned. - /// If you need fused iterator, use [`fuse`]. + /// If you need a fused iterator, use [`fuse`]. /// /// [`fuse`]: Iterator::fuse #[inline] @@ -1282,9 +1279,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter().skip(2); + /// let mut iter = a.into_iter().skip(2); /// - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// assert_eq!(iter.next(), None); /// ``` #[inline] @@ -1312,10 +1309,10 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter().take(2); + /// let mut iter = a.into_iter().take(2); /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` /// @@ -1370,7 +1367,7 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3, 4]; /// - /// let mut iter = a.iter().scan(1, |state, &x| { + /// let mut iter = a.into_iter().scan(1, |state, x| { /// // each iteration, we'll multiply the state by the element ... /// *state = *state * x; /// @@ -1448,8 +1445,8 @@ pub trait Iterator { /// /// ``` /// let data = vec![vec![1, 2, 3, 4], vec![5, 6]]; - /// let flattened = data.into_iter().flatten().collect::>(); - /// assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]); + /// let flattened: Vec<_> = data.into_iter().flatten().collect(); + /// assert_eq!(flattened, [1, 2, 3, 4, 5, 6]); /// ``` /// /// Mapping and then flattening: @@ -1483,11 +1480,11 @@ pub trait Iterator { /// ``` /// let options = vec![Some(123), Some(321), None, Some(231)]; /// let flattened_options: Vec<_> = options.into_iter().flatten().collect(); - /// assert_eq!(flattened_options, vec![123, 321, 231]); + /// assert_eq!(flattened_options, [123, 321, 231]); /// /// let results = vec![Ok(123), Ok(321), Err(456), Ok(231)]; /// let flattened_results: Vec<_> = results.into_iter().flatten().collect(); - /// assert_eq!(flattened_results, vec![123, 321, 231]); + /// assert_eq!(flattened_results, [123, 321, 231]); /// ``` /// /// Flattening only removes one level of nesting at a time: @@ -1495,11 +1492,11 @@ pub trait Iterator { /// ``` /// let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]; /// - /// let d2 = d3.iter().flatten().collect::>(); - /// assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]); + /// let d2: Vec<_> = d3.into_iter().flatten().collect(); + /// assert_eq!(d2, [[1, 2], [3, 4], [5, 6], [7, 8]]); /// - /// let d1 = d3.iter().flatten().flatten().collect::>(); - /// assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]); + /// let d1: Vec<_> = d3.into_iter().flatten().flatten().collect(); + /// assert_eq!(d1, [1, 2, 3, 4, 5, 6, 7, 8]); /// ``` /// /// Here we see that `flatten()` does not perform a "deep" flatten. @@ -1881,7 +1878,7 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// /// let doubled: Vec = a.iter() - /// .map(|&x| x * 2) + /// .map(|x| x * 2) /// .collect(); /// /// assert_eq!(vec![2, 4, 6], doubled); @@ -1897,7 +1894,7 @@ pub trait Iterator { /// /// let a = [1, 2, 3]; /// - /// let doubled: VecDeque = a.iter().map(|&x| x * 2).collect(); + /// let doubled: VecDeque = a.iter().map(|x| x * 2).collect(); /// /// assert_eq!(2, doubled[0]); /// assert_eq!(4, doubled[1]); @@ -1930,8 +1927,8 @@ pub trait Iterator { /// ``` /// let chars = ['g', 'd', 'k', 'k', 'n']; /// - /// let hello: String = chars.iter() - /// .map(|&x| x as u8) + /// let hello: String = chars.into_iter() + /// .map(|x| x as u8) /// .map(|x| (x + 1) as char) /// .collect(); /// @@ -1944,14 +1941,14 @@ pub trait Iterator { /// ``` /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")]; /// - /// let result: Result, &str> = results.iter().cloned().collect(); + /// let result: Result, &str> = results.into_iter().collect(); /// /// // gives us the first error /// assert_eq!(Err("nope"), result); /// /// let results = [Ok(1), Ok(3)]; /// - /// let result: Result, &str> = results.iter().cloned().collect(); + /// let result: Result, &str> = results.into_iter().collect(); /// /// // gives us the list of answers /// assert_eq!(Ok(vec![1, 3]), result); @@ -2073,8 +2070,8 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// let mut vec: Vec:: = vec![0, 1]; /// - /// a.iter().map(|&x| x * 2).collect_into(&mut vec); - /// a.iter().map(|&x| x * 10).collect_into(&mut vec); + /// a.iter().map(|x| x * 2).collect_into(&mut vec); + /// a.iter().map(|x| x * 10).collect_into(&mut vec); /// /// assert_eq!(vec, vec![0, 1, 2, 4, 6, 10, 20, 30]); /// ``` @@ -2087,8 +2084,8 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// let mut vec: Vec:: = Vec::with_capacity(6); /// - /// a.iter().map(|&x| x * 2).collect_into(&mut vec); - /// a.iter().map(|&x| x * 10).collect_into(&mut vec); + /// a.iter().map(|x| x * 2).collect_into(&mut vec); + /// a.iter().map(|x| x * 10).collect_into(&mut vec); /// /// assert_eq!(6, vec.capacity()); /// assert_eq!(vec, vec![2, 4, 6, 10, 20, 30]); @@ -2142,8 +2139,8 @@ pub trait Iterator { /// .into_iter() /// .partition(|n| n % 2 == 0); /// - /// assert_eq!(even, vec![2]); - /// assert_eq!(odd, vec![1, 3]); + /// assert_eq!(even, [2]); + /// assert_eq!(odd, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn partition(self, f: F) -> (B, B) @@ -2201,11 +2198,11 @@ pub trait Iterator { /// let mut a = [1, 2, 3, 4, 5, 6, 7]; /// /// // Partition in-place between evens and odds - /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0); + /// let i = a.iter_mut().partition_in_place(|n| n % 2 == 0); /// /// assert_eq!(i, 3); - /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens - /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds + /// assert!(a[..i].iter().all(|n| n % 2 == 0)); // evens + /// assert!(a[i..].iter().all(|n| n % 2 == 1)); // odds /// ``` #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize @@ -2312,7 +2309,7 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// /// // the checked sum of all of the elements of the array - /// let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x)); + /// let sum = a.into_iter().try_fold(0i8, |acc, x| acc.checked_add(x)); /// /// assert_eq!(sum, Some(6)); /// ``` @@ -2321,16 +2318,16 @@ pub trait Iterator { /// /// ``` /// let a = [10, 20, 30, 100, 40, 50]; - /// let mut it = a.iter(); + /// let mut iter = a.into_iter(); /// /// // This sum overflows when adding the 100 element - /// let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x)); + /// let sum = iter.try_fold(0i8, |acc, x| acc.checked_add(x)); /// assert_eq!(sum, None); /// /// // Because it short-circuited, the remaining elements are still /// // available through the iterator. - /// assert_eq!(it.len(), 2); - /// assert_eq!(it.next(), Some(&40)); + /// assert_eq!(iter.len(), 2); + /// assert_eq!(iter.next(), Some(40)); /// ``` /// /// While you cannot `break` from a closure, the [`ControlFlow`] type allows @@ -2683,9 +2680,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert!(a.iter().all(|&x| x > 0)); + /// assert!(a.into_iter().all(|x| x > 0)); /// - /// assert!(!a.iter().all(|&x| x > 2)); + /// assert!(!a.into_iter().all(|x| x > 2)); /// ``` /// /// Stopping at the first `false`: @@ -2693,12 +2690,12 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert!(!iter.all(|&x| x != 2)); + /// assert!(!iter.all(|x| x != 2)); /// /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -2736,9 +2733,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert!(a.iter().any(|&x| x > 0)); + /// assert!(a.into_iter().any(|x| x > 0)); /// - /// assert!(!a.iter().any(|&x| x > 5)); + /// assert!(!a.into_iter().any(|x| x > 5)); /// ``` /// /// Stopping at the first `true`: @@ -2746,12 +2743,12 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert!(iter.any(|&x| x != 2)); + /// assert!(iter.any(|x| x != 2)); /// /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(2)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -2797,9 +2794,8 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); - /// - /// assert_eq!(a.iter().find(|&&x| x == 5), None); + /// assert_eq!(a.into_iter().find(|&x| x == 2), Some(2)); + /// assert_eq!(a.into_iter().find(|&x| x == 5), None); /// ``` /// /// Stopping at the first `true`: @@ -2807,12 +2803,12 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert_eq!(iter.find(|&&x| x == 2), Some(&2)); + /// assert_eq!(iter.find(|&x| x == 2), Some(2)); /// /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// ``` /// /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`. @@ -2880,13 +2876,13 @@ pub trait Iterator { /// let a = ["1", "2", "lol", "NaN", "5"]; /// /// let is_my_num = |s: &str, search: i32| -> Result { - /// Ok(s.parse::()? == search) + /// Ok(s.parse::()? == search) /// }; /// - /// let result = a.iter().try_find(|&&s| is_my_num(s, 2)); - /// assert_eq!(result, Ok(Some(&"2"))); + /// let result = a.into_iter().try_find(|&s| is_my_num(s, 2)); + /// assert_eq!(result, Ok(Some("2"))); /// - /// let result = a.iter().try_find(|&&s| is_my_num(s, 5)); + /// let result = a.into_iter().try_find(|&s| is_my_num(s, 5)); /// assert!(result.is_err()); /// ``` /// @@ -2898,11 +2894,11 @@ pub trait Iterator { /// use std::num::NonZero; /// /// let a = [3, 5, 7, 4, 9, 0, 11u32]; - /// let result = a.iter().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two())); - /// assert_eq!(result, Some(Some(&4))); - /// let result = a.iter().take(3).try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two())); + /// let result = a.into_iter().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two())); + /// assert_eq!(result, Some(Some(4))); + /// let result = a.into_iter().take(3).try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two())); /// assert_eq!(result, Some(None)); - /// let result = a.iter().rev().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two())); + /// let result = a.into_iter().rev().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two())); /// assert_eq!(result, None); /// ``` #[inline] @@ -2967,9 +2963,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert_eq!(a.iter().position(|&x| x == 2), Some(1)); + /// assert_eq!(a.into_iter().position(|x| x == 2), Some(1)); /// - /// assert_eq!(a.iter().position(|&x| x == 5), None); + /// assert_eq!(a.into_iter().position(|x| x == 5), None); /// ``` /// /// Stopping at the first `true`: @@ -2977,15 +2973,15 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3, 4]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert_eq!(iter.position(|&x| x >= 2), Some(1)); + /// assert_eq!(iter.position(|x| x >= 2), Some(1)); /// /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(3)); /// /// // The returned index depends on iterator state - /// assert_eq!(iter.position(|&x| x == 4), Some(0)); + /// assert_eq!(iter.position(|x| x == 4), Some(0)); /// /// ``` #[inline] @@ -3035,9 +3031,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2)); + /// assert_eq!(a.into_iter().rposition(|x| x == 3), Some(2)); /// - /// assert_eq!(a.iter().rposition(|&x| x == 5), None); + /// assert_eq!(a.into_iter().rposition(|x| x == 5), None); /// ``` /// /// Stopping at the first `true`: @@ -3045,13 +3041,13 @@ pub trait Iterator { /// ``` /// let a = [-1, 2, 3, 4]; /// - /// let mut iter = a.iter(); + /// let mut iter = a.into_iter(); /// - /// assert_eq!(iter.rposition(|&x| x >= 2), Some(3)); + /// assert_eq!(iter.rposition(|x| x >= 2), Some(3)); /// /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&-1)); - /// assert_eq!(iter.next_back(), Some(&3)); + /// assert_eq!(iter.next(), Some(-1)); + /// assert_eq!(iter.next_back(), Some(3)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -3097,10 +3093,10 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3]; - /// let b: Vec = Vec::new(); + /// let b: [u32; 0] = []; /// - /// assert_eq!(a.iter().max(), Some(&3)); - /// assert_eq!(b.iter().max(), None); + /// assert_eq!(a.into_iter().max(), Some(3)); + /// assert_eq!(b.into_iter().max(), None); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -3133,10 +3129,10 @@ pub trait Iterator { /// /// ``` /// let a = [1, 2, 3]; - /// let b: Vec = Vec::new(); + /// let b: [u32; 0] = []; /// - /// assert_eq!(a.iter().min(), Some(&1)); - /// assert_eq!(b.iter().min(), None); + /// assert_eq!(a.into_iter().min(), Some(1)); + /// assert_eq!(b.into_iter().min(), None); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -3158,7 +3154,7 @@ pub trait Iterator { /// /// ``` /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10); + /// assert_eq!(a.into_iter().max_by_key(|x| x.abs()).unwrap(), -10); /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] @@ -3191,7 +3187,7 @@ pub trait Iterator { /// /// ``` /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); + /// assert_eq!(a.into_iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); /// ``` #[inline] #[stable(feature = "iter_max_by", since = "1.15.0")] @@ -3218,7 +3214,7 @@ pub trait Iterator { /// /// ``` /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0); + /// assert_eq!(a.into_iter().min_by_key(|x| x.abs()).unwrap(), 0); /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] @@ -3251,7 +3247,7 @@ pub trait Iterator { /// /// ``` /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); + /// assert_eq!(a.into_iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); /// ``` #[inline] #[stable(feature = "iter_min_by", since = "1.15.0")] @@ -3281,11 +3277,11 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut iter = a.iter().rev(); + /// let mut iter = a.into_iter().rev(); /// - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(3)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(1)); /// /// assert_eq!(iter.next(), None); /// ``` @@ -3314,7 +3310,7 @@ pub trait Iterator { /// ``` /// let a = [(1, 2), (3, 4), (5, 6)]; /// - /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); + /// let (left, right): (Vec<_>, Vec<_>) = a.into_iter().unzip(); /// /// assert_eq!(left, [1, 3, 5]); /// assert_eq!(right, [2, 4, 6]); @@ -3322,7 +3318,7 @@ pub trait Iterator { /// // you can also unzip multiple nested tuples at once /// let a = [(1, (2, 3)), (4, (5, 6))]; /// - /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip(); + /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.into_iter().unzip(); /// assert_eq!(x, [1, 4]); /// assert_eq!(y, [2, 5]); /// assert_eq!(z, [3, 6]); @@ -3354,8 +3350,8 @@ pub trait Iterator { /// // copied is the same as .map(|&x| x) /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); /// - /// assert_eq!(v_copied, vec![1, 2, 3]); - /// assert_eq!(v_map, vec![1, 2, 3]); + /// assert_eq!(v_copied, [1, 2, 3]); + /// assert_eq!(v_map, [1, 2, 3]); /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "iter_copied")] @@ -3390,8 +3386,8 @@ pub trait Iterator { /// // cloned is the same as .map(|&x| x), for integers /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); /// - /// assert_eq!(v_cloned, vec![1, 2, 3]); - /// assert_eq!(v_map, vec![1, 2, 3]); + /// assert_eq!(v_cloned, [1, 2, 3]); + /// assert_eq!(v_map, [1, 2, 3]); /// ``` /// /// To get the best performance, try to clone late: @@ -3427,15 +3423,14 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let mut it = a.iter().cycle(); + /// let mut iter = a.into_iter().cycle(); /// - /// assert_eq!(it.next(), Some(&1)); - /// assert_eq!(it.next(), Some(&2)); - /// assert_eq!(it.next(), Some(&3)); - /// assert_eq!(it.next(), Some(&1)); - /// assert_eq!(it.next(), Some(&2)); - /// assert_eq!(it.next(), Some(&3)); - /// assert_eq!(it.next(), Some(&1)); + /// loop { + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(3)); + /// # break; + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -3588,9 +3583,9 @@ pub trait Iterator { /// let xs = [1, 2, 3, 4]; /// let ys = [1, 4, 9, 16]; /// - /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less); - /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal); - /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater); + /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| x.cmp(&y)), Ordering::Less); + /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (x * x).cmp(&y)), Ordering::Equal); + /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (2 * x).cmp(&y)), Ordering::Greater); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] fn cmp_by(self, other: I, cmp: F) -> Ordering @@ -3672,15 +3667,15 @@ pub trait Iterator { /// let ys = [1.0, 4.0, 9.0, 16.0]; /// /// assert_eq!( - /// xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)), + /// xs.iter().partial_cmp_by(ys, |x, y| x.partial_cmp(&y)), /// Some(Ordering::Less) /// ); /// assert_eq!( - /// xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)), + /// xs.iter().partial_cmp_by(ys, |x, y| (x * x).partial_cmp(&y)), /// Some(Ordering::Equal) /// ); /// assert_eq!( - /// xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)), + /// xs.iter().partial_cmp_by(ys, |x, y| (2.0 * x).partial_cmp(&y)), /// Some(Ordering::Greater) /// ); /// ``` @@ -3738,7 +3733,7 @@ pub trait Iterator { /// let xs = [1, 2, 3, 4]; /// let ys = [1, 4, 9, 16]; /// - /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y)); + /// assert!(xs.iter().eq_by(ys, |x, y| x * x == y)); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] fn eq_by(self, other: I, eq: F) -> bool From 431f02d5312544d222a63d40586527ec704f2d13 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 3 May 2025 03:40:23 +0000 Subject: [PATCH 193/262] support duplicates in the opaque_types_storage --- Cargo.lock | 1 - compiler/rustc_hir_typeck/src/_match.rs | 3 +- .../src/infer/canonical/query_response.rs | 26 ++----- compiler/rustc_infer/src/infer/mod.rs | 25 ++---- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 - .../src/infer/opaque_types/table.rs | 76 ++++++++++++++++--- .../src/infer/snapshot/undo_log.rs | 2 + .../rustc_next_trait_solver/src/delegate.rs | 11 ++- .../src/solve/eval_ctxt/canonical.rs | 44 +++++++---- .../src/solve/eval_ctxt/mod.rs | 36 ++++++--- compiler/rustc_trait_selection/Cargo.toml | 1 - .../src/solve/delegate.rs | 37 +++++++-- .../opaques/duplicate-opaque-type-entries.rs | 25 ++++++ 13 files changed, 207 insertions(+), 82 deletions(-) create mode 100644 tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs diff --git a/Cargo.lock b/Cargo.lock index 98b90a47e398..4bd12ee6ae30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4516,7 +4516,6 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_transmute", - "rustc_type_ir", "smallvec", "thin-vec", "tracing", diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2e7831f16aee..61dd8c573073 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -603,7 +603,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone. ty::Infer(ty::TyVar(_)) => self .inner - .borrow() + .borrow_mut() + .opaque_types() .iter_opaque_types() .find(|(_, v)| v.ty == expected_ty) .map(|(k, _)| (k.def_id, k.args))?, diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 5220071c5005..1ae864c454f2 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -132,7 +132,13 @@ impl<'tcx> InferCtxt<'tcx> { let certainty = if errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; - let opaque_types = self.take_opaque_types_for_query_response(); + let opaque_types = self + .inner + .borrow_mut() + .opaque_type_storage + .take_opaque_types() + .map(|(k, v)| (k, v.ty)) + .collect(); Ok(QueryResponse { var_values: inference_vars, @@ -143,24 +149,6 @@ impl<'tcx> InferCtxt<'tcx> { }) } - /// Used by the new solver as that one takes the opaque types at the end of a probe - /// to deal with multiple candidates without having to recompute them. - pub fn clone_opaque_types_for_query_response( - &self, - ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { - self.inner - .borrow() - .opaque_type_storage - .opaque_types - .iter() - .map(|(k, v)| (*k, v.ty)) - .collect() - } - - fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { - self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect() - } - /// Given the (canonicalized) result to a canonical query, /// instantiates the result so it can be used, plugging in the /// values from the canonical query. (Note that the result may diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index d25542dadd59..070d285b5a63 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -31,9 +31,9 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, - GenericArgsRef, GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Term, TermKind, - Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, - TypeVisitableExt, TypingEnv, TypingMode, fold_regions, + GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey, + PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, }; use rustc_span::{Span, Symbol}; use snapshot::undo_log::InferCtxtUndoLogs; @@ -198,7 +198,7 @@ impl<'tcx> InferCtxtInner<'tcx> { } #[inline] - fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> { + pub fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> { self.opaque_type_storage.with_log(&mut self.undo_log) } @@ -224,15 +224,6 @@ impl<'tcx> InferCtxtInner<'tcx> { .expect("region constraints already solved") .with_log(&mut self.undo_log) } - - // Iterates through the opaque type definitions without taking them; this holds the - // `InferCtxtInner` lock, so make sure to not do anything with `InferCtxt` side-effects - // while looping through this. - pub fn iter_opaque_types( - &self, - ) -> impl Iterator, ty::OpaqueHiddenType<'tcx>)> { - self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v)) - } } pub struct InferCtxt<'tcx> { @@ -954,13 +945,13 @@ impl<'tcx> InferCtxt<'tcx> { } #[instrument(level = "debug", skip(self), ret)] - pub fn take_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> { - std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types) + pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect() } #[instrument(level = "debug", skip(self), ret)] - pub fn clone_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> { - self.inner.borrow().opaque_type_storage.opaque_types.clone() + pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect() } #[inline(always)] diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index ce5d2e6e17a9..df7144c31da5 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -1,5 +1,4 @@ use hir::def_id::{DefId, LocalDefId}; -use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_middle::bug; use rustc_middle::traits::ObligationCause; @@ -19,7 +18,6 @@ use crate::traits::{self, Obligation, PredicateObligations}; mod table; -pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap, OpaqueHiddenType<'tcx>>; pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable}; impl<'tcx> InferCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index ba6cc0d783dd..3c5bf9d722b9 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -1,18 +1,17 @@ +use std::ops::Deref; + +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::bug; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; use tracing::instrument; -use super::OpaqueTypeMap; use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog}; #[derive(Default, Debug, Clone)] -pub(crate) struct OpaqueTypeStorage<'tcx> { - /// Opaque types found in explicit return types and their - /// associated fresh inference variable. Writeback resolves these - /// variables to get the concrete type, which can be used to - /// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions. - pub opaque_types: OpaqueTypeMap<'tcx>, +pub struct OpaqueTypeStorage<'tcx> { + opaque_types: FxIndexMap, OpaqueHiddenType<'tcx>>, + duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, } impl<'tcx> OpaqueTypeStorage<'tcx> { @@ -33,6 +32,52 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { } } + pub(crate) fn pop_duplicate_entry(&mut self) { + let entry = self.duplicate_entries.pop(); + assert!(entry.is_some()); + } + + pub(crate) fn is_empty(&self) -> bool { + let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; + opaque_types.is_empty() && duplicate_entries.is_empty() + } + + pub(crate) fn take_opaque_types( + &mut self, + ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; + std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries)) + } + + /// Only returns the opaque types from the lookup table. These are used + /// when normalizing opaque types and have a unique key. + /// + /// Outside of canonicalization one should generally use `iter_opaque_types` + /// to also consider duplicate entries. + pub fn iter_lookup_table( + &self, + ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + self.opaque_types.iter().map(|(k, v)| (*k, *v)) + } + + /// Only returns the opaque types which are stored in `duplicate_entries`. + /// + /// These have to considered when checking all opaque type uses but are e.g. + /// irrelevant for canonical inputs as nested queries never meaningfully + /// accesses them. + pub fn iter_duplicate_entries( + &self, + ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + self.duplicate_entries.iter().copied() + } + + pub fn iter_opaque_types( + &self, + ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; + opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied()) + } + #[inline] pub(crate) fn with_log<'a>( &'a mut self, @@ -44,21 +89,27 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { impl<'tcx> Drop for OpaqueTypeStorage<'tcx> { fn drop(&mut self) { - if !self.opaque_types.is_empty() { + if !self.is_empty() { ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types))); } } } -pub(crate) struct OpaqueTypeTable<'a, 'tcx> { +pub struct OpaqueTypeTable<'a, 'tcx> { storage: &'a mut OpaqueTypeStorage<'tcx>, undo_log: &'a mut InferCtxtUndoLogs<'tcx>, } +impl<'tcx> Deref for OpaqueTypeTable<'_, 'tcx> { + type Target = OpaqueTypeStorage<'tcx>; + fn deref(&self) -> &Self::Target { + self.storage + } +} impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { #[instrument(skip(self), level = "debug")] - pub(crate) fn register( + pub fn register( &mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>, @@ -72,4 +123,9 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { self.undo_log.push(UndoLog::OpaqueTypes(key, None)); None } + + pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) { + self.storage.duplicate_entries.push((key, hidden_type)); + self.undo_log.push(UndoLog::DuplicateOpaqueType); + } } diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index ba7d8f588e68..b7412d3d6a6d 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -17,6 +17,7 @@ pub struct Snapshot<'tcx> { /// Records the "undo" data for a single operation that affects some form of inference variable. #[derive(Clone)] pub(crate) enum UndoLog<'tcx> { + DuplicateOpaqueType, OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), TypeVariables(sv::UndoLog>>), ConstUnificationTable(sv::UndoLog>>), @@ -58,6 +59,7 @@ impl_from! { impl<'tcx> Rollback> for InferCtxtInner<'tcx> { fn reverse(&mut self, undo: UndoLog<'tcx>) { match undo { + UndoLog::DuplicateOpaqueType => self.opaque_type_storage.pop_duplicate_entry(), UndoLog::OpaqueTypes(key, idx) => self.opaque_type_storage.remove(key, idx), UndoLog::TypeVariables(undo) => self.type_variable_storage.reverse(undo), UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo), diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 25493970a0ce..9e8fbd66b708 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -39,7 +39,10 @@ pub trait SolverDelegate: Deref + Sized { term: ::Term, ) -> Option::Predicate>>>; - fn clone_opaque_types_for_query_response( + fn clone_opaque_types_lookup_table( + &self, + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; + fn clone_duplicate_opaque_types( &self, ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; @@ -68,6 +71,12 @@ pub trait SolverDelegate: Deref + Sized { hidden_ty: ::Ty, span: ::Span, ) -> Option<::Ty>; + fn add_duplicate_opaque_type( + &self, + opaque_type_key: ty::OpaqueTypeKey, + hidden_ty: ::Ty, + span: ::Span, + ); fn add_item_bounds_for_hidden_type( &self, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index dded84f67686..65b10e4f23f0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -56,7 +56,10 @@ where &self, goal: Goal, ) -> (Vec, CanonicalInput) { - let opaque_types = self.delegate.clone_opaque_types_for_query_response(); + // We only care about one entry per `OpaqueTypeKey` here, + // so we only canonicalize the lookup table and ignore + // duplicate entries. + let opaque_types = self.delegate.clone_opaque_types_lookup_table(); let (goal, opaque_types) = (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate)); @@ -241,19 +244,21 @@ where Default::default() }; - ExternalConstraintsData { - region_constraints, - opaque_types: self - .delegate - .clone_opaque_types_for_query_response() - .into_iter() - // Only return *newly defined* opaque types. - .filter(|(a, _)| { - self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a) - }) - .collect(), - normalization_nested_goals, - } + // We only return *newly defined* opaque types from canonical queries. + // + // Constraints for any existing opaque types are already tracked by changes + // to the `var_values`. + let opaque_types = self + .delegate + .clone_opaque_types_lookup_table() + .into_iter() + .filter(|(a, _)| { + self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a) + }) + .chain(self.delegate.clone_duplicate_opaque_types()) + .collect(); + + ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals } } /// After calling a canonical query, we apply the constraints returned @@ -432,7 +437,16 @@ where fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey, I::Ty)]) { for &(key, ty) in opaque_types { let prev = self.delegate.register_hidden_type_in_storage(key, ty, self.origin_span); - assert_eq!(prev, None); + // We eagerly resolve inference variables when computing the query response. + // This can cause previously distinct opaque type keys to now be structurally equal. + // + // To handle this, we store any duplicate entries in a separate list to check them + // at the end of typeck/borrowck. We could alternatively eagerly equate the hidden + // types here. However, doing so is difficult as it may result in nested goals and + // any errors may make it harder to track the control flow for diagnostics. + if let Some(prev) = prev { + self.delegate.add_duplicate_opaque_type(key, prev, self.origin_span); + } } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 6dd554299a69..c13e73080550 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -14,7 +14,7 @@ use rustc_type_ir::{ TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; -use tracing::{instrument, trace}; +use tracing::{debug, instrument, trace}; use super::has_only_region_constraints; use crate::coherence; @@ -361,7 +361,20 @@ where for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span); - assert_eq!(prev, None); + // It may be possible that two entries in the opaque type storage end up + // with the same key after resolving contained inference variables. + // + // We could put them in the duplicate list but don't have to. The opaques we + // encounter here are already tracked in the caller, so there's no need to + // also store them here. We'd take them out when computing the query response + // and then discard them, as they're already present in the input. + // + // Ideally we'd drop duplicate opaque type definitions when computing + // the canonical input. This is more annoying to implement and may cause a + // perf regression, so we do it inside of the query for now. + if let Some(prev) = prev { + debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_type_storage`"); + } } if !ecx.nested_goals.is_empty() { @@ -1065,14 +1078,17 @@ where &mut self, key: ty::OpaqueTypeKey, ) -> Option<(ty::OpaqueTypeKey, I::Ty)> { - let mut matching = - self.delegate.clone_opaque_types_for_query_response().into_iter().filter( - |(candidate_key, _)| { - candidate_key.def_id == key.def_id - && DeepRejectCtxt::relate_rigid_rigid(self.cx()) - .args_may_unify(candidate_key.args, key.args) - }, - ); + // We shouldn't have any duplicate entries when using + // this function during `TypingMode::Analysis`. + let duplicate_entries = self.delegate.clone_duplicate_opaque_types(); + assert!(duplicate_entries.is_empty(), "unexpected duplicates: {duplicate_entries:?}"); + let mut matching = self.delegate.clone_opaque_types_lookup_table().into_iter().filter( + |(candidate_key, _)| { + candidate_key.def_id == key.def_id + && DeepRejectCtxt::relate_rigid_rigid(self.cx()) + .args_may_unify(candidate_key.args, key.args) + }, + ); let first = matching.next(); let second = matching.next(); assert_eq!(second, None); diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index e6de2a3978d1..1071105522d1 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -20,7 +20,6 @@ rustc_parse_format = { path = "../rustc_parse_format" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } -rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2" tracing = "0.1" diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 908c058aabec..87b8db59a78e 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -104,8 +104,23 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< .map(|obligations| obligations.into_iter().map(|obligation| obligation.as_goal()).collect()) } - fn clone_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { - self.0.clone_opaque_types_for_query_response() + fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.0 + .inner + .borrow_mut() + .opaque_types() + .iter_lookup_table() + .map(|(k, h)| (k, h.ty)) + .collect() + } + fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.0 + .inner + .borrow_mut() + .opaque_types() + .iter_duplicate_entries() + .map(|(k, h)| (k, h.ty)) + .collect() } fn make_deduplicated_outlives_constraints( @@ -156,14 +171,26 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< fn register_hidden_type_in_storage( &self, opaque_type_key: ty::OpaqueTypeKey<'tcx>, - hidden_ty: ::Ty, - span: ::Span, - ) -> Option<::Ty> { + hidden_ty: Ty<'tcx>, + span: Span, + ) -> Option> { self.0.register_hidden_type_in_storage( opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }, ) } + fn add_duplicate_opaque_type( + &self, + opaque_type_key: ty::OpaqueTypeKey<'tcx>, + hidden_ty: Ty<'tcx>, + span: Span, + ) { + self.0 + .inner + .borrow_mut() + .opaque_types() + .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }) + } fn add_item_bounds_for_hidden_type( &self, diff --git a/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs new file mode 100644 index 000000000000..e0668ac3d39f --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs @@ -0,0 +1,25 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass +#![crate_type = "lib"] +trait Eq {} +impl Eq for T {} +trait ConstrainAndEq {} +impl ConstrainAndEq for U +where + T: FnOnce() -> u32, + U: FnOnce() -> u32, + T: Eq, +{} + +fn constrain_and_eq, U>(_: T, _: U) {} +fn foo<'a>() -> impl Sized + use<'a> { + // This proves `foo<'a>: FnOnce() -> u32` and `foo<'1>: FnOnce() -> u32`, + // We constrain both `opaque<'a>` and `opaque<'1>` to `u32`, resulting in + // two distinct opaque type uses. Proving `foo<'a>: Eq>` then + // equates the two regions at which point the two opaque type keys are now + // equal. This previously caused an ICE. + constrain_and_eq(foo::<'a>, foo::<'_>); + 1u32 +} From 14782ad6874b768ce208f76a6998e2175ffce755 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 May 2025 18:17:48 +0200 Subject: [PATCH 194/262] Add new `test_main_with_exit_callback` public function in `libtest` to allow a callback to be called before exiting --- library/test/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index acaf026c679b..7f56d1e36269 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -98,6 +98,15 @@ const SECONDARY_TEST_BENCH_BENCHMARKS_VAR: &str = "__RUST_TEST_BENCH_BENCHMARKS" // The default console test runner. It accepts the command line // arguments and a vector of test_descs. pub fn test_main(args: &[String], tests: Vec, options: Option) { + test_main_with_exit_callback(args, tests, options, || {}) +} + +pub fn test_main_with_exit_callback( + args: &[String], + tests: Vec, + options: Option, + exit_callback: F, +) { let mut opts = match cli::parse_opts(args) { Some(Ok(o)) => o, Some(Err(msg)) => { @@ -151,6 +160,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Option {} Ok(false) => process::exit(ERROR_EXIT_CODE), From a84a946a3d6fc60f6485cf1d8a47845d3a416117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 6 May 2025 16:10:58 +0200 Subject: [PATCH 195/262] Handle PR not found in post-merge workflow --- .github/workflows/post-merge.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 94553608a2f4..ca088ba31fdf 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -25,12 +25,19 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | + # Give GitHub some time to propagate the information that the PR was merged + sleep 60 + # Get closest bors merge commit PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit HEAD_PR=`gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number'` + if [ -z "${HEAD_PR}" ]; then + echo "PR for commit SHA ${{ github.sha }} not found, exiting" + exit 1 + fi echo "HEAD: ${{ github.sha }} (#${HEAD_PR})" cd src/ci/citool From cdd104922df2cc62a0e82ba865d4cdc6a217090e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 6 May 2025 18:36:14 +0200 Subject: [PATCH 196/262] Use the portable `AtomicU64` --- compiler/rustc_query_system/src/dep_graph/serialized.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index b01f65a5e454..f1b609a3ca90 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -43,14 +43,14 @@ use std::cell::RefCell; use std::cmp::max; use std::marker::PhantomData; use std::sync::Arc; -use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::atomic::Ordering; use std::{iter, mem, u64}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::outline; use rustc_data_structures::profiling::SelfProfilerRef; -use rustc_data_structures::sync::{Lock, WorkerLocal, broadcast}; +use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal, broadcast}; use rustc_data_structures::unhash::UnhashMap; use rustc_index::IndexVec; use rustc_serialize::opaque::mem_encoder::MemEncoder; From 173cdafea679a9ae96b67bc74d2f623b162e1480 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 May 2025 18:18:39 +0200 Subject: [PATCH 197/262] Ensure that temporary doctest folder is correctly removed even if doctests failed --- src/librustdoc/doctest.rs | 23 ++++++++++++++++++++--- src/librustdoc/doctest/markdown.rs | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 829a9ca6e7dd..0cdf2f92a891 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -262,11 +262,21 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions Ok(None) => return, Err(error) => { eprintln!("{error}"); + // Since some files in the temporary folder are still owned and alive, we need + // to manually remove the folder. + let _ = std::fs::remove_dir_all(temp_dir.path()); std::process::exit(1); } }; - run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests); + run_tests( + opts, + &rustdoc_options, + &unused_extern_reports, + standalone_tests, + mergeable_tests, + Some(temp_dir), + ); let compiling_test_count = compiling_test_count.load(Ordering::SeqCst); @@ -316,6 +326,8 @@ pub(crate) fn run_tests( unused_extern_reports: &Arc>>, mut standalone_tests: Vec, mergeable_tests: FxIndexMap>, + // We pass this argument so we can drop it manually before using `exit`. + mut temp_dir: Option, ) { let mut test_args = Vec::with_capacity(rustdoc_options.test_args.len() + 1); test_args.insert(0, "rustdoctest".to_string()); @@ -382,9 +394,14 @@ pub(crate) fn run_tests( // `running 0 tests...`. if ran_edition_tests == 0 || !standalone_tests.is_empty() { standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice())); - test::test_main(&test_args, standalone_tests, None); + test::test_main_with_exit_callback(&test_args, standalone_tests, None, || { + // We ensure temp dir destructor is called. + std::mem::drop(temp_dir.take()); + }); } if nb_errors != 0 { + // We ensure temp dir destructor is called. + std::mem::drop(temp_dir); // libtest::ERROR_EXIT_CODE is not public but it's the same value. std::process::exit(101); } @@ -450,7 +467,7 @@ enum TestFailure { } enum DirState { - Temp(tempfile::TempDir), + Temp(TempDir), Perm(PathBuf), } diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index 497a8d7c4a75..b3a3ce08a05a 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -116,6 +116,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { &Arc::new(Mutex::new(Vec::new())), standalone_tests, mergeable_tests, + None, ); Ok(()) } From e648e5b7102422fe3c8a2393df04ec2e707673b3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 6 May 2025 10:33:04 -0700 Subject: [PATCH 198/262] rustdoc: remove unportable markdown lint and old parser Follow up https://github.com/rust-lang/rust/pull/127127 --- Cargo.lock | 16 +- src/librustdoc/Cargo.toml | 1 - src/librustdoc/lint.rs | 10 +- src/librustdoc/passes/lint.rs | 4 - .../passes/lint/unportable_markdown.rs | 145 ------------------ tests/rustdoc-ui/unportable-markdown.rs | 62 -------- tests/rustdoc-ui/unportable-markdown.stderr | 23 --- 7 files changed, 3 insertions(+), 258 deletions(-) delete mode 100644 src/librustdoc/passes/lint/unportable_markdown.rs delete mode 100644 tests/rustdoc-ui/unportable-markdown.rs delete mode 100644 tests/rustdoc-ui/unportable-markdown.stderr diff --git a/Cargo.lock b/Cargo.lock index 98b90a47e398..39519681369f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,7 +558,7 @@ dependencies = [ "if_chain", "itertools", "parking_lot", - "pulldown-cmark 0.11.3", + "pulldown-cmark", "quote", "regex", "rustc_tools_util 0.4.2", @@ -2849,17 +2849,6 @@ dependencies = [ "cc", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - [[package]] name = "pulldown-cmark" version = "0.11.3" @@ -4337,7 +4326,7 @@ version = "0.0.0" dependencies = [ "bitflags", "itertools", - "pulldown-cmark 0.11.3", + "pulldown-cmark", "rustc_arena", "rustc_ast", "rustc_ast_pretty", @@ -4622,7 +4611,6 @@ dependencies = [ "indexmap", "itertools", "minifier", - "pulldown-cmark 0.9.6", "pulldown-cmark-escape", "regex", "rustdoc-json-types", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 27ae0553c60d..dbfdd8ebd167 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -14,7 +14,6 @@ base64 = "0.21.7" itertools = "0.12" indexmap = "2" minifier = { version = "0.3.5", default-features = false } -pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false } pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index dcc27cd62e38..b09ea0568859 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -196,14 +196,6 @@ declare_rustdoc_lint! { "detects redundant explicit links in doc comments" } -declare_rustdoc_lint! { - /// This compatibility lint checks for Markdown syntax that works in the old engine but not - /// the new one. - UNPORTABLE_MARKDOWN, - Warn, - "detects markdown that is interpreted differently in different parser" -} - pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { vec![ BROKEN_INTRA_DOC_LINKS, @@ -217,7 +209,6 @@ pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { MISSING_CRATE_LEVEL_DOCS, UNESCAPED_BACKTICKS, REDUNDANT_EXPLICIT_LINKS, - UNPORTABLE_MARKDOWN, ] }); @@ -241,4 +232,5 @@ pub(crate) fn register_lints(_sess: &Session, lint_store: &mut LintStore) { .register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links"); lint_store.register_renamed("non_autolinks", "rustdoc::bare_urls"); lint_store.register_renamed("rustdoc::non_autolinks", "rustdoc::bare_urls"); + lint_store.register_removed("rustdoc::unportable_markdown", "old parser removed"); } diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index 1ecb53e61ac3..7740d14148bf 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -6,7 +6,6 @@ mod check_code_block_syntax; mod html_tags; mod redundant_explicit_links; mod unescaped_backticks; -mod unportable_markdown; use super::Pass; use crate::clean::*; @@ -49,9 +48,6 @@ impl DocVisitor<'_> for Linter<'_, '_> { } if may_have_block_comment_or_html { html_tags::visit_item(self.cx, item, hir_id, &dox); - unportable_markdown::visit_item(self.cx, item, hir_id, &dox); - } else if may_have_link { - unportable_markdown::visit_item(self.cx, item, hir_id, &dox); } } diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs deleted file mode 100644 index 95646413a2d2..000000000000 --- a/src/librustdoc/passes/lint/unportable_markdown.rs +++ /dev/null @@ -1,145 +0,0 @@ -//! Detects specific markdown syntax that's different between pulldown-cmark -//! 0.9 and 0.11. -//! -//! This is a mitigation for old parser bugs that affected some -//! real crates' docs. The old parser claimed to comply with CommonMark, -//! but it did not. These warnings will eventually be removed, -//! though some of them may become Clippy lints. -//! -//! -//! -//! - -use std::collections::{BTreeMap, BTreeSet}; - -use rustc_hir::HirId; -use rustc_lint_defs::Applicability; -use rustc_resolve::rustdoc::source_span_for_markdown_range; -use {pulldown_cmark as cmarkn, pulldown_cmark_old as cmarko}; - -use crate::clean::Item; -use crate::core::DocContext; - -pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) { - let tcx = cx.tcx; - - // P1: unintended strikethrough was fixed by requiring single-tildes to flank - // the same way underscores do, so nothing is done here - - // P2: block quotes without following space parsed wrong - // - // This is the set of starting points for block quotes with no space after - // the `>`. It is populated by the new parser, and if the old parser fails to - // clear it out, it'll produce a warning. - let mut spaceless_block_quotes = BTreeSet::new(); - - // P3: missing footnote references - // - // This is populated by listening for FootnoteReference from - // the new parser and old parser. - let mut missing_footnote_references = BTreeMap::new(); - let mut found_footnote_references = BTreeSet::new(); - - // populate problem cases from new parser - { - pub fn main_body_opts_new() -> cmarkn::Options { - cmarkn::Options::ENABLE_TABLES - | cmarkn::Options::ENABLE_FOOTNOTES - | cmarkn::Options::ENABLE_STRIKETHROUGH - | cmarkn::Options::ENABLE_TASKLISTS - | cmarkn::Options::ENABLE_SMART_PUNCTUATION - } - let parser_new = cmarkn::Parser::new_ext(dox, main_body_opts_new()).into_offset_iter(); - for (event, span) in parser_new { - if let cmarkn::Event::Start(cmarkn::Tag::BlockQuote(_)) = event { - if !dox[span.clone()].starts_with("> ") { - spaceless_block_quotes.insert(span.start); - } - } - if let cmarkn::Event::FootnoteReference(_) = event { - found_footnote_references.insert(span.start + 1); - } - } - } - - // remove cases where they don't actually differ - { - pub fn main_body_opts_old() -> cmarko::Options { - cmarko::Options::ENABLE_TABLES - | cmarko::Options::ENABLE_FOOTNOTES - | cmarko::Options::ENABLE_STRIKETHROUGH - | cmarko::Options::ENABLE_TASKLISTS - | cmarko::Options::ENABLE_SMART_PUNCTUATION - } - let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter(); - for (event, span) in parser_old { - if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event - && !dox[span.clone()].starts_with("> ") - { - spaceless_block_quotes.remove(&span.start); - } - if let cmarko::Event::FootnoteReference(_) = event - && !found_footnote_references.contains(&(span.start + 1)) - { - missing_footnote_references.insert(span.start + 1, span); - } - } - } - - for start in spaceless_block_quotes { - let (span, precise) = - source_span_for_markdown_range(tcx, dox, &(start..start + 1), &item.attrs.doc_strings) - .map(|span| (span, true)) - .unwrap_or_else(|| (item.attr_span(tcx), false)); - - tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, span, |lint| { - lint.primary_message("unportable markdown"); - lint.help("confusing block quote with no space after the `>` marker".to_string()); - if precise { - lint.span_suggestion( - span.shrink_to_hi(), - "if the quote is intended, add a space", - " ", - Applicability::MaybeIncorrect, - ); - lint.span_suggestion( - span.shrink_to_lo(), - "if it should not be a quote, escape it", - "\\", - Applicability::MaybeIncorrect, - ); - } - }); - } - for (_caret, span) in missing_footnote_references { - let (ref_span, precise) = - source_span_for_markdown_range(tcx, dox, &span, &item.attrs.doc_strings) - .map(|span| (span, true)) - .unwrap_or_else(|| (item.attr_span(tcx), false)); - - tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, ref_span, |lint| { - lint.primary_message("unportable markdown"); - if precise { - lint.span_suggestion( - ref_span.shrink_to_lo(), - "if it should not be a footnote, escape it", - "\\", - Applicability::MaybeIncorrect, - ); - } - if dox.as_bytes().get(span.end) == Some(&b'[') { - lint.help("confusing footnote reference and link"); - if precise { - lint.span_suggestion( - ref_span.shrink_to_hi(), - "if the footnote is intended, add a space", - " ", - Applicability::MaybeIncorrect, - ); - } else { - lint.help("there should be a space between the link and the footnote"); - } - } - }); - } -} diff --git a/tests/rustdoc-ui/unportable-markdown.rs b/tests/rustdoc-ui/unportable-markdown.rs deleted file mode 100644 index 105fc1e59d53..000000000000 --- a/tests/rustdoc-ui/unportable-markdown.rs +++ /dev/null @@ -1,62 +0,0 @@ -// https://internals.rust-lang.org/t/proposal-migrate-the-syntax-of-rustdoc-markdown-footnotes-to-be-compatible-with-the-syntax-used-in-github/18929 -// -// A series of test cases for CommonMark corner cases that pulldown-cmark 0.11 fixes. -// -// This version of the lint is targeted at two especially-common cases where docs got broken. -// Other differences in parsing should not warn. -#![allow(rustdoc::broken_intra_doc_links)] -#![deny(rustdoc::unportable_markdown)] - -/// -/// -/// Test footnote [^foot]. -/// -/// [^foot]: This is nested within the footnote now, but didn't used to be. -/// -/// This is a multi-paragraph footnote. -pub struct GfmFootnotes; - -/// -/// -/// test [^foo][^bar] -/// -/// [^foo]: test -/// [^bar]: test2 -pub struct FootnoteSmashedName; - -/// -/// -/// - _t -/// # test -/// t_ -pub struct NestingCornerCase; - -/// -/// -/// *~~__emphasis strike strong__~~* ~~*__strike emphasis strong__*~~ -pub struct Emphasis1; - -/// -/// -/// | -/// | -pub struct NotEnoughTable; - -/// -/// -/// foo -/// >bar -//~^ ERROR unportable markdown -pub struct BlockQuoteNoSpace; - -/// Negative test. -/// -/// foo -/// > bar -pub struct BlockQuoteSpace; - -/// Negative test. -/// -/// >bar -/// baz -pub struct BlockQuoteNoSpaceStart; diff --git a/tests/rustdoc-ui/unportable-markdown.stderr b/tests/rustdoc-ui/unportable-markdown.stderr deleted file mode 100644 index 952ae4bb6eec..000000000000 --- a/tests/rustdoc-ui/unportable-markdown.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: unportable markdown - --> $DIR/unportable-markdown.rs:48:5 - | -LL | /// >bar - | ^ - | - = help: confusing block quote with no space after the `>` marker -note: the lint level is defined here - --> $DIR/unportable-markdown.rs:8:9 - | -LL | #![deny(rustdoc::unportable_markdown)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: if the quote is intended, add a space - | -LL | /// > bar - | + -help: if it should not be a quote, escape it - | -LL | /// \>bar - | + - -error: aborting due to 1 previous error - From 43357b4a64b0bfaf6c9db14cff998a2d17b98dac Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Mon, 21 Apr 2025 16:44:42 +0530 Subject: [PATCH 199/262] Added `apxf` target feature support, under flag `apx_target_feature` --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 12 ++++++++++++ compiler/rustc_feature/src/unstable.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/target_features.rs | 1 + 4 files changed, 15 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f8706c5ee2fa..8f57f0983abb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -307,6 +307,18 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("avx10.1-512")), ("x86", "avx10.2") if get_version().0 < 20 => None, ("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")), + ("x86", "apxf") => Some(LLVMFeature::with_dependencies( + "egpr", + smallvec![ + TargetFeatureFoldStrength::Both("push2pop2"), + TargetFeatureFoldStrength::Both("ppx"), + TargetFeatureFoldStrength::Both("ndd"), + TargetFeatureFoldStrength::Both("ccmp"), + TargetFeatureFoldStrength::Both("cf"), + TargetFeatureFoldStrength::Both("nf"), + TargetFeatureFoldStrength::Both("zu"), + ], + )), (_, s) => Some(LLVMFeature::new(s)), } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1a011dfff3f7..d96089a64d08 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -316,6 +316,7 @@ declare_features! ( // Unstable `#[target_feature]` directives. (unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)), (unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)), + (unstable, apx_target_feature, "CURRENT_RUSTC_VERSION", Some(139284)), (unstable, arm_target_feature, "1.27.0", Some(44839)), (unstable, avx512_target_feature, "1.27.0", Some(44839)), (unstable, bpf_target_feature, "1.54.0", Some(44839)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3912c7dc7d69..1134209d2b85 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -459,6 +459,7 @@ symbols! { anonymous_lifetime_in_impl_trait, any, append_const_msg, + apx_target_feature, arbitrary_enum_discriminant, arbitrary_self_types, arbitrary_self_types_pointers, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index d04c8f3f2ebf..5a21925ba04e 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -393,6 +393,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]), ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), + ("apxf", Unstable(sym::apx_target_feature), &[]), ("avx", Stable, &["sse4.2"]), ( "avx10.1", From c32dc2dbda99903039a5e815451f7b376f65d35d Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Mon, 21 Apr 2025 17:23:18 +0530 Subject: [PATCH 200/262] Added apxf target feature test --- tests/ui/check-cfg/target_feature.stderr | 1 + .../feature-gate-apx-target-feature.rs | 6 ++++++ .../feature-gate-apx-target-feature.stderr | 13 +++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/ui/feature-gates/feature-gate-apx-target-feature.rs create mode 100644 tests/ui/feature-gates/feature-gate-apx-target-feature.stderr diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 3d7323298bab..eb66633f9dd7 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -27,6 +27,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `amx-tf32` `amx-tile` `amx-transpose` +`apxf` `atomics` `avx` `avx10.1` diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.rs b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs new file mode 100644 index 000000000000..a2ac4ac86ac0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs @@ -0,0 +1,6 @@ +//@ only-x86_64 +#[target_feature(enable = "apxf")] +//~^ ERROR: currently unstable +unsafe fn foo() {} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr new file mode 100644 index 000000000000..1999ab535379 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr @@ -0,0 +1,13 @@ +error[E0658]: the target feature `apxf` is currently unstable + --> $DIR/feature-gate-apx-target-feature.rs:2:18 + | +LL | #[target_feature(enable = "apxf")] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #139284 for more information + = help: add `#![feature(apx_target_feature)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From 3c1c0726ad18dc07f3ef9b9465d5997ca13e332c Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 6 May 2025 15:06:45 +0500 Subject: [PATCH 201/262] added error handle for error code > 9999 --- compiler/rustc_driver_impl/src/lib.rs | 1 + tests/ui/{explain.rs => explain/basic.rs} | 0 .../{explain.stdout => explain/basic.stdout} | 0 tests/ui/explain/error-with-no-explanation.rs | 3 + .../explain/error-with-no-explanation.stderr | 2 + tests/ui/explain/invalid-error-code.rs | 2 + tests/ui/explain/invalid-error-code.stderr | 2 + tests/ui/explain/no-E-prefix.rs | 2 + tests/ui/explain/no-E-prefix.stdout | 57 +++++++++++++++++++ tests/ui/explain/overflow-error-code.rs | 4 ++ tests/ui/explain/overflow-error-code.stderr | 2 + 11 files changed, 75 insertions(+) rename tests/ui/{explain.rs => explain/basic.rs} (100%) rename tests/ui/{explain.stdout => explain/basic.stdout} (100%) create mode 100644 tests/ui/explain/error-with-no-explanation.rs create mode 100644 tests/ui/explain/error-with-no-explanation.stderr create mode 100644 tests/ui/explain/invalid-error-code.rs create mode 100644 tests/ui/explain/invalid-error-code.stderr create mode 100644 tests/ui/explain/no-E-prefix.rs create mode 100644 tests/ui/explain/no-E-prefix.stdout create mode 100644 tests/ui/explain/overflow-error-code.rs create mode 100644 tests/ui/explain/overflow-error-code.stderr diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index fdf8053b15a6..95cfe221d3fe 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -463,6 +463,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col // Allow "E0123" or "0123" form. let upper_cased_code = code.to_ascii_uppercase(); if let Ok(code) = upper_cased_code.strip_prefix('E').unwrap_or(&upper_cased_code).parse::() + && code <= ErrCode::MAX_AS_U32 && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code)) { let mut is_in_code_block = false; diff --git a/tests/ui/explain.rs b/tests/ui/explain/basic.rs similarity index 100% rename from tests/ui/explain.rs rename to tests/ui/explain/basic.rs diff --git a/tests/ui/explain.stdout b/tests/ui/explain/basic.stdout similarity index 100% rename from tests/ui/explain.stdout rename to tests/ui/explain/basic.stdout diff --git a/tests/ui/explain/error-with-no-explanation.rs b/tests/ui/explain/error-with-no-explanation.rs new file mode 100644 index 000000000000..383820eb4580 --- /dev/null +++ b/tests/ui/explain/error-with-no-explanation.rs @@ -0,0 +1,3 @@ +// It's a valid error with no added explanation +//@ compile-flags: --explain E9999 +//~? ERROR: E9999 is not a valid error code diff --git a/tests/ui/explain/error-with-no-explanation.stderr b/tests/ui/explain/error-with-no-explanation.stderr new file mode 100644 index 000000000000..afb738cfecb9 --- /dev/null +++ b/tests/ui/explain/error-with-no-explanation.stderr @@ -0,0 +1,2 @@ +error: E9999 is not a valid error code + diff --git a/tests/ui/explain/invalid-error-code.rs b/tests/ui/explain/invalid-error-code.rs new file mode 100644 index 000000000000..114118d5196b --- /dev/null +++ b/tests/ui/explain/invalid-error-code.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --explain error_code +//~? ERROR: error_code is not a valid error code diff --git a/tests/ui/explain/invalid-error-code.stderr b/tests/ui/explain/invalid-error-code.stderr new file mode 100644 index 000000000000..c33122ea88cb --- /dev/null +++ b/tests/ui/explain/invalid-error-code.stderr @@ -0,0 +1,2 @@ +error: error_code is not a valid error code + diff --git a/tests/ui/explain/no-E-prefix.rs b/tests/ui/explain/no-E-prefix.rs new file mode 100644 index 000000000000..39c9122bfe1b --- /dev/null +++ b/tests/ui/explain/no-E-prefix.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --explain 425 +//@ check-pass diff --git a/tests/ui/explain/no-E-prefix.stdout b/tests/ui/explain/no-E-prefix.stdout new file mode 100644 index 000000000000..756b970aa7e6 --- /dev/null +++ b/tests/ui/explain/no-E-prefix.stdout @@ -0,0 +1,57 @@ +An unresolved name was used. + +Erroneous code examples: + +``` +something_that_doesnt_exist::foo; +// error: unresolved name `something_that_doesnt_exist::foo` + +// or: + +trait Foo { + fn bar() { + Self; // error: unresolved name `Self` + } +} + +// or: + +let x = unknown_variable; // error: unresolved name `unknown_variable` +``` + +Please verify that the name wasn't misspelled and ensure that the +identifier being referred to is valid for the given situation. Example: + +``` +enum something_that_does_exist { + Foo, +} +``` + +Or: + +``` +mod something_that_does_exist { + pub static foo : i32 = 0i32; +} + +something_that_does_exist::foo; // ok! +``` + +Or: + +``` +let unknown_variable = 12u32; +let x = unknown_variable; // ok! +``` + +If the item is not defined in the current module, it must be imported using a +`use` statement, like so: + +``` +use foo::bar; +bar(); +``` + +If the item you are importing is not defined in some super-module of the +current module, then it must also be declared as public (e.g., `pub fn`). diff --git a/tests/ui/explain/overflow-error-code.rs b/tests/ui/explain/overflow-error-code.rs new file mode 100644 index 000000000000..284d5cddb35a --- /dev/null +++ b/tests/ui/explain/overflow-error-code.rs @@ -0,0 +1,4 @@ +// Check that we don't crash on error codes exceeding our internal limit. +// issue: +//@ compile-flags: --explain E10000 +//~? ERROR: E10000 is not a valid error code diff --git a/tests/ui/explain/overflow-error-code.stderr b/tests/ui/explain/overflow-error-code.stderr new file mode 100644 index 000000000000..67e584ea32e1 --- /dev/null +++ b/tests/ui/explain/overflow-error-code.stderr @@ -0,0 +1,2 @@ +error: E10000 is not a valid error code + From 636a138cdae2da2b261a54681a2910ce21ed8019 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 May 2025 19:27:25 +0000 Subject: [PATCH 202/262] Structurally resolve in check_ref_cast --- compiler/rustc_hir_typeck/src/cast.rs | 15 ++++++------- .../ui/cast/cast-alias-of-array-to-element.rs | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 tests/ui/cast/cast-alias-of-array-to-element.rs diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index caf36ba47bd7..5bfc3e810d9f 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -1051,20 +1051,19 @@ impl<'a, 'tcx> CastCheck<'tcx> { fn check_ref_cast( &self, fcx: &FnCtxt<'a, 'tcx>, - m_expr: ty::TypeAndMut<'tcx>, - m_cast: ty::TypeAndMut<'tcx>, + mut m_expr: ty::TypeAndMut<'tcx>, + mut m_cast: ty::TypeAndMut<'tcx>, ) -> Result> { // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const + m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty); + m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty); + if m_expr.mutbl >= m_cast.mutbl && let ty::Array(ety, _) = m_expr.ty.kind() && fcx.can_eq(fcx.param_env, *ety, m_cast.ty) { - // Due to the limitations of LLVM global constants, - // region pointers end up pointing at copies of - // vector elements instead of the original values. - // To allow raw pointers to work correctly, we - // need to special-case obtaining a raw pointer - // from a region pointer to a vector. + // Due to historical reasons we allow directly casting references of + // arrays into raw pointers of their element type. // Coerce to a raw pointer so that we generate RawPtr in MIR. let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl); diff --git a/tests/ui/cast/cast-alias-of-array-to-element.rs b/tests/ui/cast/cast-alias-of-array-to-element.rs new file mode 100644 index 000000000000..124d0e0346f0 --- /dev/null +++ b/tests/ui/cast/cast-alias-of-array-to-element.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . +// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast. + +trait Mirror { + type Assoc: ?Sized; +} +impl Mirror for T { + type Assoc = T; +} + +struct W<'a>(&'a <[f32; 0] as Mirror>::Assoc); + +fn foo(x: W<'_>) -> *const f32 { + x.0 as *const f32 +} + +fn main() {} From 6a4af821b00a1e55f44c80846c1a438a3c41dee5 Mon Sep 17 00:00:00 2001 From: Jon Bauman Date: Tue, 6 May 2025 13:19:42 -0700 Subject: [PATCH 203/262] Update rc.rs docs Update comment per review feedback --- library/alloc/src/rc.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 247afc628326..4b8ea708e7e5 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -3536,11 +3536,11 @@ impl Default for Weak { } } -// NOTE: We wrapping_add here to deal with mem::forget safely. In particular -// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then -// you can free the allocation while outstanding Rcs (or Weaks) exist. -// We abort because this is such a degenerate scenario that we don't care about -// what happens -- no real program should ever experience this. +// NOTE: If you mem::forget Rcs (or Weaks), drop is skipped and the ref-count +// is not decremented, meaning the ref-count can overflow, and then you can +// free the allocation while outstanding Rcs (or Weaks) exist, which would be +// unsound. We abort because this is such a degenerate scenario that we don't +// care about what happens -- no real program should ever experience this. // // This should have negligible overhead since you don't actually need to // clone these much in Rust thanks to ownership and move-semantics. From 49ac393688510f0f36627f5899bf0ededd26a8de Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Wed, 7 May 2025 00:11:05 +0200 Subject: [PATCH 204/262] fix typo in autorefs lint doc example The documentation is talking about other way using only raw pointers, but the example was use `std::slice::from_raw_parts_mut` which also create a reference. `std::ptr::slice_from_raw_parts_mut` should be used instead, and it also highlights the benefit of raw pointer manipulation compared to dereference, as the function doesn't need to be unsafe anymore. Moreover, [`unsafe_op_in_unsafe_fn`](https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html) warning has been enabled since Edition 2024, so I've updated the examples to use unsafe blocks. --- compiler/rustc_lint/src/autorefs.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index ddab13190beb..91d58d92466a 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs @@ -15,9 +15,9 @@ declare_lint! { /// /// ```rust /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] { - /// &raw mut (*ptr)[..16] - /// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`, - /// // implicitly creating a reference + /// unsafe { &raw mut (*ptr)[..16] } + /// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`, + /// // implicitly creating a reference /// } /// ``` /// @@ -34,17 +34,17 @@ declare_lint! { /// /// ```rust /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] { - /// &raw mut (&mut *ptr)[..16] + /// unsafe { &raw mut (&mut *ptr)[..16] } /// } /// ``` /// /// Otherwise try to find an alternative way to achive your goals using only raw pointers: /// /// ```rust - /// use std::slice; + /// use std::ptr; /// - /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] { - /// slice::from_raw_parts_mut(ptr.cast(), 16) + /// fn fun(ptr: *mut [u8]) -> *mut [u8] { + /// ptr::slice_from_raw_parts_mut(ptr.cast(), 16) /// } /// ``` pub DANGEROUS_IMPLICIT_AUTOREFS, From 4de822c3d2a3c13633b0c08ae98d05aada94eabf Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 6 May 2025 23:30:47 +0000 Subject: [PATCH 205/262] Update `compiler-builtins` to 0.1.158 Includes the following changes: * Require `target_has_atomic = "ptr"` for runtime feature detection [1]: https://github.com/rust-lang/compiler-builtins/pull/909 --- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index a94ed7be8c78..5100b4d8176d 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.157" +version = "0.1.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f103f5a97b25e3ed7134dee586e90bbb0496b33ba41816f0e7274e5bb73b50" +checksum = "164cdc689e4c6d69417f77a5f48be240c291e84fbef0b1281755dc754b19c809" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index ebfcf8759fa1..51ddc9bf9fc9 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -16,7 +16,7 @@ bench = false [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.157", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.158", features = ['rustc-dep-of-std'] } [features] compiler-builtins-mem = ['compiler_builtins/mem'] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 06bec74523bb..e548daa1ad0d 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.157" } +compiler_builtins = { version = "=0.1.158" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From b41d8bde00930d80f07b7aa90cc0a8e6bd423413 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 17 Apr 2025 02:33:24 -0700 Subject: [PATCH 206/262] let deref patterns participate in usefulness/exhaustiveness This does not yet handle the case of mixed deref patterns with normal constructors; it'll ICE in `Constructor::is_covered_by`. That'll be fixed in a later commit. --- .../rustc_pattern_analysis/src/constructor.rs | 22 +++++++++++++++++++ compiler/rustc_pattern_analysis/src/rustc.rs | 18 ++++++++++----- .../rustc_pattern_analysis/src/usefulness.rs | 4 +++- .../src/language-features/deref-patterns.md | 3 +-- tests/ui/pattern/deref-patterns/bindings.rs | 2 -- .../pattern/deref-patterns/closure_capture.rs | 8 +++---- tests/ui/pattern/deref-patterns/deref-box.rs | 10 ++++----- .../deref-patterns/implicit-cow-deref.rs | 4 ---- 8 files changed, 47 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 4ce868f014f4..f7a4931c1114 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -696,6 +696,10 @@ pub enum Constructor { F128Range(IeeeFloat, IeeeFloat, RangeEnd), /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately. Str(Cx::StrLit), + /// Deref patterns (enabled by the `deref_patterns` feature) provide a way of matching on a + /// smart pointer ADT through its pointee. They don't directly correspond to ADT constructors, + /// and currently are not supported alongside them. Carries the type of the pointee. + DerefPattern(Cx::Ty), /// Constants that must not be matched structurally. They are treated as black boxes for the /// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a /// match exhaustive. @@ -740,6 +744,7 @@ impl Clone for Constructor { Constructor::F64Range(lo, hi, end) => Constructor::F64Range(*lo, *hi, *end), Constructor::F128Range(lo, hi, end) => Constructor::F128Range(*lo, *hi, *end), Constructor::Str(value) => Constructor::Str(value.clone()), + Constructor::DerefPattern(ty) => Constructor::DerefPattern(ty.clone()), Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()), Constructor::Or => Constructor::Or, Constructor::Never => Constructor::Never, @@ -856,6 +861,10 @@ impl Constructor { } (Slice(self_slice), Slice(other_slice)) => self_slice.is_covered_by(*other_slice), + // Deref patterns only interact with other deref patterns. Prior to usefulness analysis, + // we ensure they don't appear alongside any other non-wild non-opaque constructors. + (DerefPattern(_), DerefPattern(_)) => true, + // Opaque constructors don't interact with anything unless they come from the // syntactically identical pattern. (Opaque(self_id), Opaque(other_id)) => self_id == other_id, @@ -932,6 +941,7 @@ impl Constructor { F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?, F128Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?, Str(value) => write!(f, "{value:?}")?, + DerefPattern(_) => write!(f, "deref!({:?})", fields.next().unwrap())?, Opaque(..) => write!(f, "")?, Or => { for pat in fields { @@ -1039,8 +1049,17 @@ impl ConstructorSet { let mut missing = Vec::new(); // Constructors in `ctors`, except wildcards and opaques. let mut seen = Vec::new(); + // If we see a deref pattern, it must be the only non-wildcard non-opaque constructor; we + // ensure this prior to analysis. + let mut deref_pat_present = false; for ctor in ctors.cloned() { match ctor { + DerefPattern(..) => { + if !deref_pat_present { + deref_pat_present = true; + present.push(ctor); + } + } Opaque(..) => present.push(ctor), Wildcard => {} // discard wildcards _ => seen.push(ctor), @@ -1048,6 +1067,9 @@ impl ConstructorSet { } match self { + _ if deref_pat_present => { + // Deref patterns are the only constructor; nothing is missing. + } ConstructorSet::Struct { empty } => { if !seen.is_empty() { present.push(Struct); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 7c12f69f14c1..050b48d082b7 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -269,6 +269,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } _ => bug!("bad slice pattern {:?} {:?}", ctor, ty), }, + DerefPattern(pointee_ty) => reveal_and_alloc(cx, once(pointee_ty.inner())), Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing | PrivateUninhabited | Wildcard => &[], @@ -296,7 +297,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } _ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"), }, - Ref => 1, + Ref | DerefPattern(_) => 1, Slice(slice) => slice.arity(), Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing @@ -493,11 +494,15 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ), }; } - PatKind::DerefPattern { .. } => { - // FIXME(deref_patterns): At least detect that `box _` is irrefutable. - fields = vec![]; - arity = 0; - ctor = Opaque(OpaqueId::new()); + PatKind::DerefPattern { subpattern, .. } => { + // NB(deref_patterns): This assumes the deref pattern is matching on a trusted + // `DerefPure` type. If the `Deref` impl isn't trusted, exhaustiveness must take + // into account that multiple calls to deref may return different results. Hence + // multiple deref! patterns cannot be exhaustive together unless each is exhaustive + // by itself. + fields = vec![self.lower_pat(subpattern).at_index(0)]; + arity = 1; + ctor = DerefPattern(cx.reveal_opaque_ty(subpattern.ty)); } PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => { match ty.kind() { @@ -874,6 +879,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap(); s } + DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])), Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { SliceKind::FixedLen(len) => (len, false), diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 11ebbea07fa4..53638f2a57dd 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -702,6 +702,7 @@ //! - `ui/consts/const_in_pattern` //! - `ui/rfc-2008-non-exhaustive` //! - `ui/half-open-range-patterns` +//! - `ui/pattern/deref-patterns` //! - probably many others //! //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific @@ -866,7 +867,8 @@ impl PlaceValidity { /// inside `&` and union fields where validity is reset to `MaybeInvalid`. fn specialize(self, ctor: &Constructor) -> Self { // We preserve validity except when we go inside a reference or a union field. - if matches!(ctor, Constructor::Ref | Constructor::UnionField) { + if matches!(ctor, Constructor::Ref | Constructor::DerefPattern(_) | Constructor::UnionField) + { // Validity of `x: &T` does not imply validity of `*x: T`. MaybeInvalid } else { diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md index fb6df290cc12..4c3d456b9af8 100644 --- a/src/doc/unstable-book/src/language-features/deref-patterns.md +++ b/src/doc/unstable-book/src/language-features/deref-patterns.md @@ -60,8 +60,7 @@ Like [`box_patterns`], deref patterns may move out of boxes: # #![feature(deref_patterns)] # #![allow(incomplete_features)] struct NoCopy; -// Match exhaustiveness analysis is not yet implemented. -let deref!(x) = Box::new(NoCopy) else { unreachable!() }; +let deref!(x) = Box::new(NoCopy); drop::(x); ``` diff --git a/tests/ui/pattern/deref-patterns/bindings.rs b/tests/ui/pattern/deref-patterns/bindings.rs index ac48e3ffefcc..92c01d737bac 100644 --- a/tests/ui/pattern/deref-patterns/bindings.rs +++ b/tests/ui/pattern/deref-patterns/bindings.rs @@ -13,7 +13,6 @@ fn simple_vec(vec: Vec) -> u32 { deref!([x]) => x, deref!([1, x]) => x + 200, deref!(ref slice) => slice.iter().sum(), - _ => 2000, } } @@ -25,7 +24,6 @@ fn simple_vec(vec: Vec) -> u32 { [x] => x, [1, x] => x + 200, deref!(ref slice) => slice.iter().sum(), - _ => 2000, } } diff --git a/tests/ui/pattern/deref-patterns/closure_capture.rs b/tests/ui/pattern/deref-patterns/closure_capture.rs index cf78eeda1d5a..497ec622b0cf 100644 --- a/tests/ui/pattern/deref-patterns/closure_capture.rs +++ b/tests/ui/pattern/deref-patterns/closure_capture.rs @@ -9,7 +9,7 @@ struct NoCopy; fn main() { let b = Rc::new("aaa".to_string()); let f = || { - let deref!(ref s) = b else { unreachable!() }; + let deref!(ref s) = b; assert_eq!(s.len(), 3); }; assert_eq!(b.len(), 3); @@ -26,7 +26,7 @@ fn main() { let mut b = "aaa".to_string(); let mut f = || { - let deref!(ref mut s) = b else { unreachable!() }; + let deref!(ref mut s) = b; s.make_ascii_uppercase(); }; f(); @@ -53,7 +53,7 @@ fn main() { let b = Box::new(NoCopy); let f = || { // this should move out of the box rather than borrow. - let deref!(x) = b else { unreachable!() }; + let deref!(x) = b; drop::(x); }; f(); @@ -61,7 +61,7 @@ fn main() { let b = Box::new((NoCopy,)); let f = || { // this should move out of the box rather than borrow. - let (x,) = b else { unreachable!() }; + let (x,) = b; drop::(x); }; f(); diff --git a/tests/ui/pattern/deref-patterns/deref-box.rs b/tests/ui/pattern/deref-patterns/deref-box.rs index 2d0a8d01972e..39b23dcab51e 100644 --- a/tests/ui/pattern/deref-patterns/deref-box.rs +++ b/tests/ui/pattern/deref-patterns/deref-box.rs @@ -6,18 +6,18 @@ #![expect(incomplete_features)] fn unbox_1(b: Box) -> T { - let deref!(x) = b else { unreachable!() }; + let deref!(x) = b; x } fn unbox_2(b: Box<(T,)>) -> T { - let (x,) = b else { unreachable!() }; + let (x,) = b; x } fn unbox_separately(b: Box<(T, T)>) -> (T, T) { - let (x, _) = b else { unreachable!() }; - let (_, y) = b else { unreachable!() }; + let (x, _) = b; + let (_, y) = b; (x, y) } @@ -31,7 +31,7 @@ fn main() { // test that borrowing from a box also works let mut b = "hi".to_owned().into_boxed_str(); - let deref!(ref mut s) = b else { unreachable!() }; + let deref!(ref mut s) = b; s.make_ascii_uppercase(); assert_eq!(&*b, "HI"); } diff --git a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs index 04c83d4c33fd..24770261edc5 100644 --- a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs +++ b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs @@ -11,7 +11,6 @@ fn main() { match cow { [..] => {} - _ => unreachable!(), } match cow { @@ -22,14 +21,12 @@ fn main() { match Rc::new(&cow) { Cow::Borrowed { 0: _ } => {} Cow::Owned { 0: _ } => unreachable!(), - _ => unreachable!(), } let cow_of_cow: Cow<'_, Cow<'static, [u8]>> = Cow::Owned(cow); match cow_of_cow { [..] => {} - _ => unreachable!(), } // This matches on the outer `Cow` (the owned one). @@ -41,6 +38,5 @@ fn main() { match Rc::new(&cow_of_cow) { Cow::Borrowed { 0: _ } => unreachable!(), Cow::Owned { 0: _ } => {} - _ => unreachable!(), } } From cf43bba1e5ec87838fca248f36d940f2923576c2 Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 18 Apr 2025 03:03:57 -0700 Subject: [PATCH 207/262] add exhaustiveness/usefulness tests for deref patterns --- .../deref-patterns/usefulness/empty-types.rs | 47 ++++++++++++++ .../usefulness/empty-types.stderr | 38 +++++++++++ .../usefulness/non-exhaustive.rs | 28 +++++++++ .../usefulness/non-exhaustive.stderr | 63 +++++++++++++++++++ .../usefulness/unreachable-patterns.rs | 33 ++++++++++ .../usefulness/unreachable-patterns.stderr | 60 ++++++++++++++++++ 6 files changed, 269 insertions(+) create mode 100644 tests/ui/pattern/deref-patterns/usefulness/empty-types.rs create mode 100644 tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr create mode 100644 tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs create mode 100644 tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr create mode 100644 tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs create mode 100644 tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs new file mode 100644 index 000000000000..03419030e72f --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs @@ -0,0 +1,47 @@ +//! Test that the place behind a deref pattern is treated as maybe-invalid, and thus empty arms +//! cannot be omitted. This is handled the same as for refs and union fields, so this leaves the +//! bulk of the testing to `tests/ui/pattern/usefulness/empty-types.rs`. +// FIXME(deref_patterns): On stabilization, cases for deref patterns could be worked into that file +// to keep the tests for empty types in one place and test more thoroughly. +#![feature(deref_patterns)] +#![expect(incomplete_features)] +#![deny(unreachable_patterns)] + +enum Void {} + +fn main() { + // Sanity check: matching on an empty type without pointer indirection lets us omit arms. + let opt_void: Option = None; + match opt_void { + None => {} + } + + // But if we hide it behind a smart pointer, we need an arm. + let box_opt_void: Box> = Box::new(None); + match box_opt_void { + //~^ ERROR non-exhaustive patterns: `deref!(Some(_))` not covered + None => {} + } + match box_opt_void { + None => {} + Some(_) => {} + } + match box_opt_void { + None => {} + _ => {} + } + + // For consistency, this behaves the same as if we manually dereferenced the scrutinee. + match *box_opt_void { + //~^ ERROR non-exhaustive patterns: `Some(_)` not covered + None => {} + } + match *box_opt_void { + None => {} + Some(_) => {} + } + match *box_opt_void { + None => {} + _ => {} + } +} diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr new file mode 100644 index 000000000000..e32477085661 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr @@ -0,0 +1,38 @@ +error[E0004]: non-exhaustive patterns: `deref!(Some(_))` not covered + --> $DIR/empty-types.rs:21:11 + | +LL | match box_opt_void { + | ^^^^^^^^^^^^ pattern `deref!(Some(_))` not covered + | +note: `Box>` defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: the matched value is of type `Box>` + = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ None => {}, +LL + deref!(Some(_)) => todo!() + | + +error[E0004]: non-exhaustive patterns: `Some(_)` not covered + --> $DIR/empty-types.rs:35:11 + | +LL | match *box_opt_void { + | ^^^^^^^^^^^^^ pattern `Some(_)` not covered + | +note: `Option` defined here + --> $SRC_DIR/core/src/option.rs:LL:COL + ::: $SRC_DIR/core/src/option.rs:LL:COL + | + = note: not covered + = note: the matched value is of type `Option` + = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ None => {}, +LL + Some(_) => todo!() + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs new file mode 100644 index 000000000000..704cae8bdbc4 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs @@ -0,0 +1,28 @@ +//! Test non-exhaustive matches involving deref patterns. +#![feature(deref_patterns)] +#![expect(incomplete_features)] +#![deny(unreachable_patterns)] + +fn main() { + match Box::new(false) { + //~^ ERROR non-exhaustive patterns: `deref!(true)` not covered + false => {} + } + + match Box::new(Box::new(false)) { + //~^ ERROR non-exhaustive patterns: `deref!(deref!(false))` not covered + true => {} + } + + match Box::new((true, Box::new(false))) { + //~^ ERROR non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered + (true, false) => {} + (false, true) => {} + } + + enum T { A, B, C } + match Box::new((Box::new(T::A), Box::new(T::A))) { + //~^ ERROR non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered + (T::A | T::B, T::C) => {} + } +} diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr new file mode 100644 index 000000000000..55fa84bafde2 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr @@ -0,0 +1,63 @@ +error[E0004]: non-exhaustive patterns: `deref!(true)` not covered + --> $DIR/non-exhaustive.rs:7:11 + | +LL | match Box::new(false) { + | ^^^^^^^^^^^^^^^ pattern `deref!(true)` not covered + | +note: `Box` defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: the matched value is of type `Box` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ false => {}, +LL + deref!(true) => todo!() + | + +error[E0004]: non-exhaustive patterns: `deref!(deref!(false))` not covered + --> $DIR/non-exhaustive.rs:12:11 + | +LL | match Box::new(Box::new(false)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!(deref!(false))` not covered + | +note: `Box>` defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: the matched value is of type `Box>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ true => {}, +LL + deref!(deref!(false)) => todo!() + | + +error[E0004]: non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered + --> $DIR/non-exhaustive.rs:17:11 + | +LL | match Box::new((true, Box::new(false))) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ patterns `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered + | +note: `Box<(bool, Box)>` defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: the matched value is of type `Box<(bool, Box)>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms + | +LL ~ (false, true) => {}, +LL + deref!((false, deref!(false))) | deref!((true, deref!(true))) => todo!() + | + +error[E0004]: non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered + --> $DIR/non-exhaustive.rs:24:11 + | +LL | match Box::new((Box::new(T::A), Box::new(T::A))) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!((deref!(T::C), _))` not covered + | +note: `Box<(Box, Box)>` defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: the matched value is of type `Box<(Box, Box)>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ (T::A | T::B, T::C) => {}, +LL + deref!((deref!(T::C), _)) => todo!() + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs new file mode 100644 index 000000000000..2677fc54dedc --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs @@ -0,0 +1,33 @@ +//! Test unreachable patterns involving deref patterns. +#![feature(deref_patterns)] +#![expect(incomplete_features)] +#![deny(unreachable_patterns)] + +fn main() { + match Box::new(false) { + true => {} + false => {} + false => {} //~ ERROR unreachable pattern + } + + match Box::new(Box::new(false)) { + true => {} + false => {} + true => {} //~ ERROR unreachable pattern + } + + match Box::new((true, Box::new(false))) { + (true, _) => {} + (_, true) => {} + (false, false) => {} + _ => {} //~ ERROR unreachable pattern + } + + enum T { A, B, C } + match Box::new((Box::new(T::A), Box::new(T::A))) { + (T::A | T::B, T::A | T::C) => {} + (T::A, T::C) => {} //~ ERROR unreachable pattern + (T::B, T::A) => {} //~ ERROR unreachable pattern + _ => {} + } +} diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr new file mode 100644 index 000000000000..045e11be3196 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr @@ -0,0 +1,60 @@ +error: unreachable pattern + --> $DIR/unreachable-patterns.rs:10:9 + | +LL | false => {} + | ----- matches all the relevant values +LL | false => {} + | ^^^^^ no value can reach this + | +note: the lint level is defined here + --> $DIR/unreachable-patterns.rs:4:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/unreachable-patterns.rs:16:9 + | +LL | true => {} + | ---- matches all the relevant values +LL | false => {} +LL | true => {} + | ^^^^ no value can reach this + +error: unreachable pattern + --> $DIR/unreachable-patterns.rs:23:9 + | +LL | _ => {} + | ^ no value can reach this + | +note: multiple earlier patterns match some of the same values + --> $DIR/unreachable-patterns.rs:23:9 + | +LL | (true, _) => {} + | --------- matches some of the same values +LL | (_, true) => {} + | --------- matches some of the same values +LL | (false, false) => {} + | -------------- matches some of the same values +LL | _ => {} + | ^ collectively making this unreachable + +error: unreachable pattern + --> $DIR/unreachable-patterns.rs:29:9 + | +LL | (T::A | T::B, T::A | T::C) => {} + | -------------------------- matches all the relevant values +LL | (T::A, T::C) => {} + | ^^^^^^^^^^^^ no value can reach this + +error: unreachable pattern + --> $DIR/unreachable-patterns.rs:30:9 + | +LL | (T::A | T::B, T::A | T::C) => {} + | -------------------------- matches all the relevant values +LL | (T::A, T::C) => {} +LL | (T::B, T::A) => {} + | ^^^^^^^^^^^^ no value can reach this + +error: aborting due to 5 previous errors + From fb261a179d2c210785b6e9005201e262dac801b5 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 20 Apr 2025 23:57:09 -0700 Subject: [PATCH 208/262] error early when mixing deref patterns with normal constructors Without adding proper support for mixed exhaustiveness, mixing deref patterns with normal constructors would either violate `ConstructorSet::split`'s invariant 4 or 7. We'd either be ignoring rows with normal constructors or we'd have problems in unspecialization from non-disjoint constructors. Checking mixed exhaustivenss similarly to how unions are currently checked should work, but the diagnostics for unions are confusing. Since mixing deref patterns with normal constructors is pretty niche (currently it only makes sense for `Cow`), emitting an error lets us avoid committing to supporting mixed exhaustiveness without a good answer for the diagnostics. --- compiler/rustc_pattern_analysis/messages.ftl | 4 ++ compiler/rustc_pattern_analysis/src/errors.rs | 14 ++++- compiler/rustc_pattern_analysis/src/rustc.rs | 53 +++++++++++++++++++ .../usefulness/mixed-constructors.rs | 48 +++++++++++++++++ .../usefulness/mixed-constructors.stderr | 43 +++++++++++++++ 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs create mode 100644 tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr diff --git a/compiler/rustc_pattern_analysis/messages.ftl b/compiler/rustc_pattern_analysis/messages.ftl index 41a1d958f109..d3a3107f8e89 100644 --- a/compiler/rustc_pattern_analysis/messages.ftl +++ b/compiler/rustc_pattern_analysis/messages.ftl @@ -6,6 +6,10 @@ pattern_analysis_excluside_range_missing_max = exclusive range missing `{$max}` .label = this range doesn't match `{$max}` because `..` is an exclusive range .suggestion = use an inclusive range instead +pattern_analysis_mixed_deref_pattern_constructors = mix of deref patterns and normal constructors + .deref_pattern_label = matches on the result of dereferencing `{$smart_pointer_ty}` + .normal_constructor_label = matches directly on `{$smart_pointer_ty}` + pattern_analysis_non_exhaustive_omitted_pattern = some variants are not matched explicitly .help = ensure that all variants are matched explicitly by adding the suggested match arms .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs index e60930d6cd21..156ba9737673 100644 --- a/compiler/rustc_pattern_analysis/src/errors.rs +++ b/compiler/rustc_pattern_analysis/src/errors.rs @@ -1,5 +1,5 @@ use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic}; -use rustc_macros::{LintDiagnostic, Subdiagnostic}; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -133,3 +133,15 @@ pub(crate) struct NonExhaustiveOmittedPatternLintOnArm { pub lint_level: &'static str, pub lint_name: &'static str, } + +#[derive(Diagnostic)] +#[diag(pattern_analysis_mixed_deref_pattern_constructors)] +pub(crate) struct MixedDerefPatternConstructors<'tcx> { + #[primary_span] + pub spans: Vec, + pub smart_pointer_ty: Ty<'tcx>, + #[label(pattern_analysis_deref_pattern_label)] + pub deref_pattern_label: Span, + #[label(pattern_analysis_normal_constructor_label)] + pub normal_constructor_label: Span, +} diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 050b48d082b7..a89d01dcbbe4 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -1106,6 +1106,14 @@ pub fn analyze_match<'p, 'tcx>( scrut_ty: Ty<'tcx>, ) -> Result, ErrorGuaranteed> { let scrut_ty = tycx.reveal_opaque_ty(scrut_ty); + + // The analysis doesn't support deref patterns mixed with normal constructors; error if present. + // FIXME(deref_patterns): This only needs to run when a deref pattern was found during lowering. + if tycx.tcx.features().deref_patterns() { + let pat_column = PatternColumn::new(arms); + detect_mixed_deref_pat_ctors(tycx, &pat_column)?; + } + let scrut_validity = PlaceValidity::from_bool(tycx.known_valid_scrutinee); let report = compute_match_usefulness( tycx, @@ -1125,6 +1133,51 @@ pub fn analyze_match<'p, 'tcx>( Ok(report) } +// FIXME(deref_patterns): Currently it's the responsibility of the frontend (rustc or rust-analyzer) +// to ensure that deref patterns don't appear in the same column as normal constructors. Deref +// patterns aren't currently implemented in rust-analyzer, but should they be, the columnwise check +// here could be made generic and shared between frontends. +fn detect_mixed_deref_pat_ctors<'p, 'tcx>( + cx: &RustcPatCtxt<'p, 'tcx>, + column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>, +) -> Result<(), ErrorGuaranteed> { + let Some(&ty) = column.head_ty() else { + return Ok(()); + }; + + // Check for a mix of deref patterns and normal constructors. + let mut normal_ctor_span = None; + let mut deref_pat_span = None; + for pat in column.iter() { + match pat.ctor() { + // The analysis can handle mixing deref patterns with wildcards and opaque patterns. + Wildcard | Opaque(_) => {} + DerefPattern(_) => deref_pat_span = Some(pat.data().span), + // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`. + _ => normal_ctor_span = Some(pat.data().span), + } + } + if let Some(normal_constructor_label) = normal_ctor_span + && let Some(deref_pattern_label) = deref_pat_span + { + return Err(cx.tcx.dcx().emit_err(errors::MixedDerefPatternConstructors { + spans: vec![deref_pattern_label, normal_constructor_label], + smart_pointer_ty: ty.inner(), + deref_pattern_label, + normal_constructor_label, + })); + } + + // Specialize and recurse into the patterns' fields. + let set = column.analyze_ctors(cx, &ty)?; + for ctor in set.present { + for specialized_column in column.specialize(cx, &ty, &ctor).iter() { + detect_mixed_deref_pat_ctors(cx, specialized_column)?; + } + } + Ok(()) +} + struct RecursiveOpaque { def_id: DefId, } diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs new file mode 100644 index 000000000000..f567dc07bb59 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs @@ -0,0 +1,48 @@ +//! Test matches with a mix of ADT constructors and deref patterns. Currently, usefulness analysis +//! doesn't support this, so make sure we catch it beforehand. As a consequence, it takes priority +//! over non-exhaustive match and unreachable pattern errors. +#![feature(deref_patterns)] +#![expect(incomplete_features)] +#![deny(unreachable_patterns)] + +use std::borrow::Cow; + +fn main() { + let cow: Cow<'static, bool> = Cow::Borrowed(&false); + + match cow { + true => {} + //~v ERROR mix of deref patterns and normal constructors + false => {} + Cow::Borrowed(_) => {} + } + + match cow { + Cow::Owned(_) => {} + Cow::Borrowed(_) => {} + true => {} + //~^ ERROR mix of deref patterns and normal constructors + } + + match cow { + _ => {} + Cow::Owned(_) => {} + false => {} + //~^ ERROR mix of deref patterns and normal constructors + } + + match (cow, 0) { + (Cow::Owned(_), 0) => {} + (Cow::Borrowed(_), 0) => {} + (true, 0) => {} + //~^ ERROR mix of deref patterns and normal constructors + } + + match (0, cow) { + (0, Cow::Owned(_)) => {} + (0, Cow::Borrowed(_)) => {} + _ => {} + (1, true) => {} + //~^ ERROR mix of deref patterns and normal constructors + } +} diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr new file mode 100644 index 000000000000..5ad24164b985 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr @@ -0,0 +1,43 @@ +error: mix of deref patterns and normal constructors + --> $DIR/mixed-constructors.rs:16:9 + | +LL | false => {} + | ^^^^^ matches on the result of dereferencing `Cow<'_, bool>` +LL | Cow::Borrowed(_) => {} + | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>` + +error: mix of deref patterns and normal constructors + --> $DIR/mixed-constructors.rs:22:9 + | +LL | Cow::Borrowed(_) => {} + | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>` +LL | true => {} + | ^^^^ matches on the result of dereferencing `Cow<'_, bool>` + +error: mix of deref patterns and normal constructors + --> $DIR/mixed-constructors.rs:29:9 + | +LL | Cow::Owned(_) => {} + | ^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>` +LL | false => {} + | ^^^^^ matches on the result of dereferencing `Cow<'_, bool>` + +error: mix of deref patterns and normal constructors + --> $DIR/mixed-constructors.rs:36:10 + | +LL | (Cow::Borrowed(_), 0) => {} + | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>` +LL | (true, 0) => {} + | ^^^^ matches on the result of dereferencing `Cow<'_, bool>` + +error: mix of deref patterns and normal constructors + --> $DIR/mixed-constructors.rs:43:13 + | +LL | (0, Cow::Borrowed(_)) => {} + | ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>` +LL | _ => {} +LL | (1, true) => {} + | ^^^^ matches on the result of dereferencing `Cow<'_, bool>` + +error: aborting due to 5 previous errors + From 09fed2d2f440fff2179ca9373bb16e40fc81d935 Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 21 Apr 2025 02:34:02 -0700 Subject: [PATCH 209/262] add stubbed-out cases for rust-analyzer rust-analyzer doesn't construct `DerefPattern(_)` constructors, so these shouldn't crash. It looks like this is how slice patterns are implemented too. --- .../crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 6323d8b71b72..068fc22f2cac 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -301,6 +301,7 @@ impl<'db> MatchCheckCtx<'db> { // ignore this issue. Ref => PatKind::Deref { subpattern: subpatterns.next().unwrap() }, Slice(_) => unimplemented!(), + DerefPattern(_) => unimplemented!(), &Str(void) => match void {}, Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild, Never => PatKind::Never, @@ -351,6 +352,7 @@ impl PatCx for MatchCheckCtx<'_> { }, Ref => 1, Slice(..) => unimplemented!(), + DerefPattern(..) => unimplemented!(), Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0, @@ -411,6 +413,7 @@ impl PatCx for MatchCheckCtx<'_> { } }, Slice(_) => unreachable!("Found a `Slice` constructor in match checking"), + DerefPattern(_) => unreachable!("Found a `DerefPattern` constructor in match checking"), Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => { From d81472f2669c266c13209855e089ff96303092fc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Apr 2025 07:52:30 +1000 Subject: [PATCH 210/262] Eliminate `word_or_empty` methods. To get rid of the `Ident::empty` uses. This requires introducing `PathParser::word_sym`, as an alternative to `PathParser::word`. --- .../src/attributes/allow_unstable.rs | 2 +- .../src/attributes/deprecation.rs | 26 +++++------ .../rustc_attr_parsing/src/attributes/repr.rs | 46 +++++++++++-------- .../src/attributes/stability.rs | 25 +++++----- compiler/rustc_attr_parsing/src/parser.rs | 15 +----- 5 files changed, 54 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index d37ede86cfd2..c1d95d07f4c6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -53,7 +53,7 @@ fn parse_unstable<'a>( for param in list.mixed() { let param_span = param.span(); - if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) { + if let Some(ident) = param.meta_item().and_then(|i| i.path_without_args().word()) { res.push(ident.name); } else { cx.emit_err(session_diagnostics::ExpectsFeatures { diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index 7d1417446b21..fb3d5f57d4fa 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -1,5 +1,4 @@ use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation}; -use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol, sym}; use super::SingleAttributeParser; @@ -13,16 +12,13 @@ pub(crate) struct DeprecationParser; fn get( cx: &AcceptContext<'_>, - ident: Ident, + name: Symbol, param_span: Span, arg: &ArgParser<'_>, item: &Option, ) -> Option { if item.is_some() { - cx.emit_err(session_diagnostics::MultipleItem { - span: param_span, - item: ident.to_string(), - }); + cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() }); return None; } if let Some(v) = arg.name_value() { @@ -83,16 +79,16 @@ impl SingleAttributeParser for DeprecationParser { return None; }; - let (ident, arg) = param.word_or_empty(); + let ident_name = param.path_without_args().word_sym(); - match ident.name { - sym::since => { - since = Some(get(cx, ident, param_span, arg, &since)?); + match ident_name { + Some(name @ sym::since) => { + since = Some(get(cx, name, param_span, param.args(), &since)?); } - sym::note => { - note = Some(get(cx, ident, param_span, arg, ¬e)?); + Some(name @ sym::note) => { + note = Some(get(cx, name, param_span, param.args(), ¬e)?); } - sym::suggestion => { + Some(name @ sym::suggestion) => { if !features.deprecated_suggestion() { cx.emit_err(session_diagnostics::DeprecatedItemSuggestion { span: param_span, @@ -101,12 +97,12 @@ impl SingleAttributeParser for DeprecationParser { }); } - suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?); + suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?); } _ => { cx.emit_err(session_diagnostics::UnknownMetaItem { span: param_span, - item: ident.to_string(), + item: param.path_without_args().to_string(), expected: if features.deprecated_suggestion() { &["since", "note", "suggestion"] } else { diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 26ca637faec6..bc0819565700 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -96,57 +96,65 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option { - cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span }); + match (name, args) { + (Some(sym::align), ArgParser::NoArgs) => { + cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span }); None } - (sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align), + (Some(sym::align), ArgParser::List(l)) => { + parse_repr_align(cx, l, param.span(), AlignKind::Align) + } - (sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)), - (sym::packed, ArgParser::List(l)) => { + (Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)), + (Some(sym::packed), ArgParser::List(l)) => { parse_repr_align(cx, l, param.span(), AlignKind::Packed) } - (sym::align | sym::packed, ArgParser::NameValue(l)) => { + (Some(sym::align | sym::packed), ArgParser::NameValue(l)) => { cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric { span: param.span(), // FIXME(jdonszelmann) can just be a string in the diag type - repr_arg: &ident.to_string(), + repr_arg: &ident.unwrap().to_string(), cause: IncorrectReprFormatGenericCause::from_lit_kind( param.span(), &l.value_as_lit().kind, - ident.name.as_str(), + ident.unwrap().as_str(), ), }); None } - (sym::Rust, ArgParser::NoArgs) => Some(ReprRust), - (sym::C, ArgParser::NoArgs) => Some(ReprC), - (sym::simd, ArgParser::NoArgs) => Some(ReprSimd), - (sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent), - (i @ int_pat!(), ArgParser::NoArgs) => { + (Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust), + (Some(sym::C), ArgParser::NoArgs) => Some(ReprC), + (Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd), + (Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent), + (Some(i @ int_pat!()), ArgParser::NoArgs) => { // int_pat!() should make sure it always parses Some(ReprInt(int_type_of_word(i).unwrap())) } ( - sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), + Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()), ArgParser::NameValue(_), ) => { cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), - name: ident.to_string(), + name: ident.unwrap().to_string(), }); None } - (sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => { + ( + Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()), + ArgParser::List(_), + ) => { cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), - name: ident.to_string(), + name: ident.unwrap().to_string(), }); None } diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index bdad6b50186d..cd1f21d92e7e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -242,9 +242,9 @@ pub(crate) fn parse_stability( return None; }; - match param.word_or_empty_without_args().name { - sym::feature => insert_value_into_option_or_error(cx, ¶m, &mut feature)?, - sym::since => insert_value_into_option_or_error(cx, ¶m, &mut since)?, + match param.path_without_args().word_sym() { + Some(sym::feature) => insert_value_into_option_or_error(cx, ¶m, &mut feature)?, + Some(sym::since) => insert_value_into_option_or_error(cx, ¶m, &mut since)?, _ => { cx.emit_err(session_diagnostics::UnknownMetaItem { span: param_span, @@ -310,11 +310,10 @@ pub(crate) fn parse_unstability( return None; }; - let (word, args) = param.word_or_empty(); - match word.name { - sym::feature => insert_value_into_option_or_error(cx, ¶m, &mut feature)?, - sym::reason => insert_value_into_option_or_error(cx, ¶m, &mut reason)?, - sym::issue => { + match param.path_without_args().word_sym() { + Some(sym::feature) => insert_value_into_option_or_error(cx, ¶m, &mut feature)?, + Some(sym::reason) => insert_value_into_option_or_error(cx, ¶m, &mut reason)?, + Some(sym::issue) => { insert_value_into_option_or_error(cx, ¶m, &mut issue)?; // These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item @@ -328,7 +327,7 @@ pub(crate) fn parse_unstability( session_diagnostics::InvalidIssueString { span: param.span(), cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( - args.name_value().unwrap().value_span, + param.args().name_value().unwrap().value_span, err.kind(), ), }, @@ -338,13 +337,15 @@ pub(crate) fn parse_unstability( }, }; } - sym::soft => { - if !args.no_args() { + Some(sym::soft) => { + if !param.args().no_args() { cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() }); } is_soft = true; } - sym::implied_by => insert_value_into_option_or_error(cx, ¶m, &mut implied_by)?, + Some(sym::implied_by) => { + insert_value_into_option_or_error(cx, ¶m, &mut implied_by)? + } _ => { cx.emit_err(session_diagnostics::UnknownMetaItem { span: param.span(), diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 40aa39711d3e..077d953cfa31 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -78,8 +78,8 @@ impl<'a> PathParser<'a> { (self.len() == 1).then(|| **self.segments().next().as_ref().unwrap()) } - pub fn word_or_empty(&self) -> Ident { - self.word().unwrap_or_else(Ident::empty) + pub fn word_sym(&self) -> Option { + self.word().map(|ident| ident.name) } /// Asserts that this MetaItem is some specific word. @@ -284,11 +284,6 @@ impl<'a> MetaItemParser<'a> { Some(self.word()?.0) } - /// Like [`word`](Self::word), but returns an empty symbol instead of None - pub fn word_or_empty_without_args(&self) -> Ident { - self.word_or_empty().0 - } - /// Asserts that this MetaItem starts with a word, or single segment path. /// /// Some examples: @@ -300,12 +295,6 @@ impl<'a> MetaItemParser<'a> { Some((path.word()?, args)) } - /// Like [`word`](Self::word), but returns an empty symbol instead of None - pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) { - let (path, args) = self.deconstruct(); - (path.word().unwrap_or(Ident::empty()), args) - } - /// Asserts that this MetaItem starts with some specific word. /// /// See [`word`](Self::word) for examples of what a word is. From 603766cd727a5c8b8151a542ab53cf8f84a38f4f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 May 2025 12:50:56 +1000 Subject: [PATCH 211/262] Avoid some unwraps. By using `@` patterns more. Also, use `Symbol` more in a couple of errors to avoid some unnecessary conversions to strings. This even removes a lifetime. --- .../rustc_attr_parsing/src/attributes/repr.rs | 45 +++++++++++-------- .../src/session_diagnostics.rs | 36 +++++++-------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index bc0819565700..43dfb85a7c41 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -96,9 +96,12 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option, param: &MetaItemParser<'_>) -> Option { + (Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => { cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric { span: param.span(), // FIXME(jdonszelmann) can just be a string in the diag type - repr_arg: &ident.unwrap().to_string(), + repr_arg: name, cause: IncorrectReprFormatGenericCause::from_lit_kind( param.span(), &l.value_as_lit().kind, - ident.unwrap().as_str(), + name, ), }); None @@ -133,29 +136,35 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option Some(ReprC), (Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd), (Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent), - (Some(i @ int_pat!()), ArgParser::NoArgs) => { + (Some(name @ int_pat!()), ArgParser::NoArgs) => { // int_pat!() should make sure it always parses - Some(ReprInt(int_type_of_word(i).unwrap())) + Some(ReprInt(int_type_of_word(name).unwrap())) } ( - Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()), + Some( + name @ sym::Rust + | name @ sym::C + | name @ sym::simd + | name @ sym::transparent + | name @ int_pat!(), + ), ArgParser::NameValue(_), ) => { - cx.emit_err(session_diagnostics::InvalidReprHintNoValue { - span: param.span(), - name: ident.unwrap().to_string(), - }); + cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name }); None } ( - Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()), + Some( + name @ sym::Rust + | name @ sym::C + | name @ sym::simd + | name @ sym::transparent + | name @ int_pat!(), + ), ArgParser::List(_), ) => { - cx.emit_err(session_diagnostics::InvalidReprHintNoParen { - span: param.span(), - name: ident.unwrap().to_string(), - }); + cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name }); None } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 9d34b807ac2f..2c434175b4b6 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -204,7 +204,7 @@ pub(crate) struct InvalidReprHintNoParen { #[primary_span] pub span: Span, - pub name: String, + pub name: Symbol, } #[derive(Diagnostic)] @@ -213,7 +213,7 @@ pub(crate) struct InvalidReprHintNoValue { #[primary_span] pub span: Span, - pub name: String, + pub name: Symbol, } /// Error code: E0565 @@ -295,21 +295,21 @@ pub(crate) struct IncorrectReprFormatExpectInteger { #[derive(Diagnostic)] #[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)] -pub(crate) struct IncorrectReprFormatGeneric<'a> { +pub(crate) struct IncorrectReprFormatGeneric { #[primary_span] pub span: Span, - pub repr_arg: &'a str, + pub repr_arg: Symbol, #[subdiagnostic] - pub cause: Option>, + pub cause: Option, } #[derive(Subdiagnostic)] -pub(crate) enum IncorrectReprFormatGenericCause<'a> { +pub(crate) enum IncorrectReprFormatGenericCause { #[suggestion( attr_parsing_suggestion, - code = "{name}({int})", + code = "{name}({value})", applicability = "machine-applicable" )] Int { @@ -317,15 +317,15 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { span: Span, #[skip_arg] - name: &'a str, + name: Symbol, #[skip_arg] - int: u128, + value: u128, }, #[suggestion( attr_parsing_suggestion, - code = "{name}({symbol})", + code = "{name}({value})", applicability = "machine-applicable" )] Symbol { @@ -333,20 +333,20 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { span: Span, #[skip_arg] - name: &'a str, + name: Symbol, #[skip_arg] - symbol: Symbol, + value: Symbol, }, } -impl<'a> IncorrectReprFormatGenericCause<'a> { - pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { - match kind { - ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - Some(Self::Int { span, name, int: int.get() }) +impl IncorrectReprFormatGenericCause { + pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option { + match *kind { + ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => { + Some(Self::Int { span, name, value: value.get() }) } - ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }), + ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }), _ => None, } } From fe64184b162cc6fc43b9e44ecaa8c065afbf7ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=87=E9=80=B8?= Date: Mon, 28 Apr 2025 22:48:45 +0800 Subject: [PATCH 212/262] Fix backtrace for cygwin --- library/backtrace | 2 +- library/std/Cargo.toml | 2 +- library/windows_targets/src/lib.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/library/backtrace b/library/backtrace index 9d2c34e7e63a..6c882eb11984 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 9d2c34e7e63afe1e71c333b247065e3b7ba4d883 +Subproject commit 6c882eb11984d737f62e85f36703effaf34c2453 diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 602af4a0447e..778f77e8eafa 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -57,7 +57,7 @@ object = { version = "0.36.0", default-features = false, optional = true, featur 'archive', ] } -[target.'cfg(windows)'.dependencies.windows-targets] +[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies.windows-targets] path = "../windows_targets" [dev-dependencies] diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs index c7d158584ebd..bce54c5ffcef 100644 --- a/library/windows_targets/src/lib.rs +++ b/library/windows_targets/src/lib.rs @@ -34,6 +34,7 @@ pub macro link { } #[cfg(not(feature = "windows_raw_dylib"))] +#[cfg(not(target_os = "cygwin"))] // Cygwin doesn't need these libs #[cfg_attr(target_vendor = "win7", link(name = "advapi32"))] #[link(name = "ntdll")] #[link(name = "userenv")] From 392880c004836724dfe7600e6f2e0db5f8bad168 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Wed, 7 May 2025 08:04:21 +0000 Subject: [PATCH 213/262] Fix regression from #140393 for espidf / horizon / nuttx / vita --- library/std/src/sys/process/unix/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs index 2e8b38f7de1b..ee8fd8b2ca3c 100644 --- a/library/std/src/sys/process/unix/mod.rs +++ b/library/std/src/sys/process/unix/mod.rs @@ -11,6 +11,7 @@ cfg_if::cfg_if! { } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] { mod unsupported; use unsupported as imp; + pub use unsupported::output; } else { mod unix; use unix as imp; From f46806fb14d9ef9ba76b836019f9e2705b213c97 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 7 May 2025 17:27:56 +0800 Subject: [PATCH 214/262] Add ui test suggest-remove-deref-issue-140166 Signed-off-by: xizheyin --- .../suggest-remove-deref-issue-140166.rs | 18 +++++++++++++ .../suggest-remove-deref-issue-140166.stderr | 26 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/traits/suggest-remove-deref-issue-140166.rs create mode 100644 tests/ui/traits/suggest-remove-deref-issue-140166.stderr diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.rs b/tests/ui/traits/suggest-remove-deref-issue-140166.rs new file mode 100644 index 000000000000..1b832c7eba5c --- /dev/null +++ b/tests/ui/traits/suggest-remove-deref-issue-140166.rs @@ -0,0 +1,18 @@ +trait Trait {} + +struct Chars; +impl Trait for Chars {} + +struct FlatMap(T); +impl std::fmt::Debug for FlatMap { + fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + unimplemented!() + } +} + +fn lol() { + format_args!("{:?}", FlatMap(&Chars)); + //~^ ERROR the trait bound `&Chars: Trait` is not satisfied [E0277] +} + +fn main() {} diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.stderr b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr new file mode 100644 index 000000000000..8bdcf5981a50 --- /dev/null +++ b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr @@ -0,0 +1,26 @@ +error[E0277]: the trait bound `&Chars: Trait` is not satisfied + --> $DIR/suggest-remove-deref-issue-140166.rs:14:26 + | +LL | format_args!("{:?}", FlatMap(&Chars)); + | ---- ^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&Chars` + | | + | required by a bound introduced by this call + | +note: required for `FlatMap<&Chars>` to implement `Debug` + --> $DIR/suggest-remove-deref-issue-140166.rs:7:16 + | +LL | impl std::fmt::Debug for FlatMap { + | ----- ^^^^^^^^^^^^^^^ ^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL +help: consider removing the leading `&`-reference + | +LL - format_args!("{:?}", FlatMap(&Chars)); +LL + format_args!("{:?}", latMap(&Chars)); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 4e26480c74112d4050e24a6a096cd0710c688b20 Mon Sep 17 00:00:00 2001 From: Adrian Friedli Date: Wed, 7 May 2025 16:01:39 +0200 Subject: [PATCH 215/262] add armv5te-unknown-linux-gnueabi target maintainer --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../armv5te-unknown-linux-gnueabi.md | 29 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index cf41f5b86a85..a3939e5a5c45 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -58,6 +58,7 @@ - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) + - [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md) - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md) - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 50c7ae3ef8db..60002a5f9e5d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -156,7 +156,7 @@ target | std | notes [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC [`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian [`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat -`armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23) +[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23) `armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3 [`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android `armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27) diff --git a/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md new file mode 100644 index 000000000000..1baf1049994b --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md @@ -0,0 +1,29 @@ +# `armv5te-unknown-linux-gnueabi` + +**Tier: 2** + +This target supports Linux programs with glibc on ARMv5TE CPUs without +floating-point units. + +## Target maintainers + +[@koalatux](https://github.com/koalatux) + +## Requirements + +The target is for cross-compilation only. Host tools are not supported. +std is fully supported. + +## Building the target + +Because this target is tier 2, artifacts are available from rustup. + +## Building Rust programs + +For building rust programs, you might want to specify GCC as linker in +`.cargo/config.toml` as follows: + +```toml +[target.armv5te-unknown-linux-gnueabi] +linker = "arm-linux-gnueabi-gcc" +``` From 442ae63257708962de9d43c4f9b44130e7926321 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 May 2025 16:05:15 +0200 Subject: [PATCH 216/262] Add regression test for #139899 --- .../rustdoc-tempdir-removal/compile-error.rs | 5 +++ .../run-make/rustdoc-tempdir-removal/rmake.rs | 34 +++++++++++++++++++ .../rustdoc-tempdir-removal/run-error.rs | 3 ++ 3 files changed, 42 insertions(+) create mode 100644 tests/run-make/rustdoc-tempdir-removal/compile-error.rs create mode 100644 tests/run-make/rustdoc-tempdir-removal/rmake.rs create mode 100644 tests/run-make/rustdoc-tempdir-removal/run-error.rs diff --git a/tests/run-make/rustdoc-tempdir-removal/compile-error.rs b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs new file mode 100644 index 000000000000..66a3b3f270b7 --- /dev/null +++ b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs @@ -0,0 +1,5 @@ +#![doc(test(attr(deny(warnings))))] + +//! ``` +//! let a = 12; +//! ``` diff --git a/tests/run-make/rustdoc-tempdir-removal/rmake.rs b/tests/run-make/rustdoc-tempdir-removal/rmake.rs new file mode 100644 index 000000000000..bd87f05b7cf5 --- /dev/null +++ b/tests/run-make/rustdoc-tempdir-removal/rmake.rs @@ -0,0 +1,34 @@ +// This test ensures that no temporary folder is "left behind" when doctests fail for any reason. + +//@ only-linux + +use std::path::Path; + +use run_make_support::{path, rfs, rustdoc}; + +fn run_doctest_and_check_tmpdir(tmp_dir: &Path, doctest: &str, edition: &str) { + let output = + rustdoc().input(doctest).env("TMPDIR", tmp_dir).arg("--test").edition(edition).run_fail(); + + output.assert_exit_code(101).assert_stdout_contains( + "test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out", + ); + + rfs::read_dir_entries(tmp_dir, |entry| { + panic!("Found an item inside the temporary folder: {entry:?}"); + }); +} + +fn run_doctest_and_check_tmpdir_for_edition(tmp_dir: &Path, edition: &str) { + run_doctest_and_check_tmpdir(tmp_dir, "compile-error.rs", edition); + run_doctest_and_check_tmpdir(tmp_dir, "run-error.rs", edition); +} + +fn main() { + let tmp_dir = path("tmp"); + rfs::create_dir(&tmp_dir); + + run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2018"); + // We use the 2024 edition to check that it's also working for merged doctests. + run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2024"); +} diff --git a/tests/run-make/rustdoc-tempdir-removal/run-error.rs b/tests/run-make/rustdoc-tempdir-removal/run-error.rs new file mode 100644 index 000000000000..4ac95f6dd61a --- /dev/null +++ b/tests/run-make/rustdoc-tempdir-removal/run-error.rs @@ -0,0 +1,3 @@ +//! ``` +//! panic!(); +//! ``` From cd2dc67eadb6105790520223965deef6c5887f7a Mon Sep 17 00:00:00 2001 From: Jesus Checa Hidalgo Date: Wed, 7 May 2025 16:32:46 +0200 Subject: [PATCH 217/262] run-make-support: set rustc dylib path for cargo wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some run-make tests invoke Cargo via run_make_support::cargo(), but fail to execute correctly when rustc is built without rpath. In these setups, runtime loading of rustc’s shared libraries fails unless the appropriate dynamic library path is set manually. This commit updates the cargo() wrapper to call set_host_compiler_dylib_path(), aligning its behavior with the existing rustc() wrapper: https://github.com/rust-lang/rust/blob/f76c7367c6363d33ddb5a93b5de0d158b2d827f6/src/tools/run-make-support/src/external_deps/rustc.rs#L39 This ensures that Cargo invocations during tests inherit the necessary dylib paths, avoiding errors related to missing shared libraries in rpath-less builds. Fixes part of #140738 --- src/tools/run-make-support/src/external_deps/cargo.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/run-make-support/src/external_deps/cargo.rs b/src/tools/run-make-support/src/external_deps/cargo.rs index e91d101cb995..8da9f002c41b 100644 --- a/src/tools/run-make-support/src/external_deps/cargo.rs +++ b/src/tools/run-make-support/src/external_deps/cargo.rs @@ -1,8 +1,11 @@ use crate::command::Command; use crate::env_var; +use crate::util::set_host_compiler_dylib_path; /// Returns a command that can be used to invoke cargo. The cargo is provided by compiletest /// through the `CARGO` env var. pub fn cargo() -> Command { - Command::new(env_var("CARGO")) + let mut cmd = Command::new(env_var("CARGO")); + set_host_compiler_dylib_path(&mut cmd); + cmd } From b922da3586ce01a4bf174db09624a1d0a424d5d9 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 6 May 2025 15:45:04 +0800 Subject: [PATCH 218/262] Use `parse_param_general` when parsing `(T, U)->R` in `parse_path_segment` Signed-off-by: xizheyin Co-authored-by: Vadim Petrochenkov --- compiler/rustc_parse/messages.ftl | 10 +++++ compiler/rustc_parse/src/errors.rs | 24 ++++++++++ compiler/rustc_parse/src/parser/item.rs | 15 +++++-- compiler/rustc_parse/src/parser/path.rs | 29 +++++++++++- .../fn-trait-use-named-params-issue-140169.rs | 14 ++++-- ...trait-use-named-params-issue-140169.stderr | 44 ++++++++++++------ ...hesized-type-arguments-ice-issue-122345.rs | 8 ++-- ...zed-type-arguments-ice-issue-122345.stderr | 45 +++++++++++++++---- .../issues/issue-103748-ICE-wrong-braces.rs | 5 +-- .../issue-103748-ICE-wrong-braces.stderr | 39 ++-------------- 10 files changed, 158 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index ac4f7ed64e22..907368178505 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -702,6 +702,16 @@ parse_parenthesized_lifetime_suggestion = remove the parentheses parse_path_double_colon = path separator must be a double colon .suggestion = use a double colon instead + +parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters + .suggestion = remove the attributes + +parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters + .suggestion = remove the `...` + +parse_path_found_named_params = `Trait(...)` syntax does not support named parameters + .suggestion = remove the parameter name + parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies .suggestion = give this argument a name or use an underscore to ignore it diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 6a6fb0eb9b5b..7bd78f77fa63 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1591,6 +1591,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword { pub fn_token_span: Span, } +#[derive(Diagnostic)] +#[diag(parse_path_found_named_params)] +pub(crate) struct FnPathFoundNamedParams { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = "")] + pub named_param_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_path_found_c_variadic_params)] +pub(crate) struct PathFoundCVariadicParams { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = "")] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_path_found_attribute_in_params)] +pub(crate) struct PathFoundAttributeInParams { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = "")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_path_double_colon)] pub(crate) struct PathSingleColon { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 4be8a90368d2..babc55ccc0f9 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2894,7 +2894,7 @@ impl<'a> Parser<'a> { let (mut params, _) = self.parse_paren_comma_seq(|p| { p.recover_vcs_conflict_marker(); let snapshot = p.create_snapshot_for_diagnostic(); - let param = p.parse_param_general(req_name, first_param).or_else(|e| { + let param = p.parse_param_general(req_name, first_param, true).or_else(|e| { let guar = e.emit(); // When parsing a param failed, we should check to make the span of the param // not contain '(' before it. @@ -2922,7 +2922,13 @@ impl<'a> Parser<'a> { /// Parses a single function parameter. /// /// - `self` is syntactically allowed when `first_param` holds. - fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> { + /// - `recover_arg_parse` is used to recover from a failed argument parse. + pub(super) fn parse_param_general( + &mut self, + req_name: ReqName, + first_param: bool, + recover_arg_parse: bool, + ) -> PResult<'a, Param> { let lo = self.token.span; let attrs = self.parse_outer_attributes()?; self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { @@ -2990,12 +2996,13 @@ impl<'a> Parser<'a> { // If this is a C-variadic argument and we hit an error, return the error. Err(err) if this.token == token::DotDotDot => return Err(err), Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err), - // Recover from attempting to parse the argument as a type without pattern. - Err(err) => { + Err(err) if recover_arg_parse => { + // Recover from attempting to parse the argument as a type without pattern. err.cancel(); this.restore_snapshot(parser_snapshot_before_ty); this.recover_arg_parse()? } + Err(err) => return Err(err), } }; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 1093e4f4af0a..9bce2fa74caa 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -15,7 +15,11 @@ use tracing::debug; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::errors::{self, PathSingleColon, PathTripleColon}; +use crate::ast::{PatKind, TyKind}; +use crate::errors::{ + self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams, + PathSingleColon, PathTripleColon, +}; use crate::exp; use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; @@ -396,7 +400,28 @@ impl<'a> Parser<'a> { snapshot = Some(self.create_snapshot_for_diagnostic()); } - let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) { + let dcx = self.dcx(); + let parse_params_result = self.parse_paren_comma_seq(|p| { + let param = p.parse_param_general(|_| false, false, false); + param.map(move |param| { + if !matches!(param.pat.kind, PatKind::Missing) { + dcx.emit_err(FnPathFoundNamedParams { + named_param_span: param.pat.span, + }); + } + if matches!(param.ty.kind, TyKind::CVarArgs) { + dcx.emit_err(PathFoundCVariadicParams { span: param.pat.span }); + } + if !param.attrs.is_empty() { + dcx.emit_err(PathFoundAttributeInParams { + span: param.attrs[0].span, + }); + } + param.ty + }) + }); + + let (inputs, _) = match parse_params_result { Ok(output) => output, Err(mut error) if prev_token_before_parsing == token::PathSep => { error.span_label( diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs index fae5f6c15193..218450abd499 100644 --- a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs +++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs @@ -1,6 +1,12 @@ -fn g(_: fn(a: u8)) {} -fn x(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` -fn y(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` -fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} //~ ERROR expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` +fn f1(_: fn(a: u8)) {} +fn f2(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters +fn f3(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters +fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {} +//~^ ERROR `Trait(...)` syntax does not support named parameters +//~| ERROR `Trait(...)` syntax does not support named parameters +fn f5(_: impl Fn(u8, ...)) {} +//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters +fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {} +//~^ ERROR `Trait(...)` syntax does not support attributes in parameters fn main(){} diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr index e599afb1345f..b72d5b7b3bc4 100644 --- a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr +++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr @@ -1,20 +1,38 @@ -error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:25 +error: `Trait(...)` syntax does not support named parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22 | -LL | fn x(_: impl Fn(u8, vvvv: u8)) {} - | ^ expected one of 7 possible tokens +LL | fn f2(_: impl Fn(u8, vvvv: u8)) {} + | ^^^^ help: remove the parameter name -error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:21 +error: `Trait(...)` syntax does not support named parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18 | -LL | fn y(_: impl Fn(aaaa: u8, u8)) {} - | ^ expected one of 7 possible tokens +LL | fn f3(_: impl Fn(aaaa: u8, u8)) {} + | ^^^^ help: remove the parameter name -error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:21 +error: `Trait(...)` syntax does not support named parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18 | -LL | fn z(_: impl Fn(aaaa: u8, vvvv: u8)) {} - | ^ expected one of 7 possible tokens +LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {} + | ^^^^ help: remove the parameter name -error: aborting due to 3 previous errors +error: `Trait(...)` syntax does not support named parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28 + | +LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {} + | ^^^^ help: remove the parameter name + +error: `Trait(...)` syntax does not support c_variadic parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:7:22 + | +LL | fn f5(_: impl Fn(u8, ...)) {} + | ^^^ help: remove the `...` + +error: `Trait(...)` syntax does not support attributes in parameters + --> $DIR/fn-trait-use-named-params-issue-140169.rs:9:22 + | +LL | fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attributes + +error: aborting due to 6 previous errors diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs index 6bfe16ae37d2..db25ce440893 100644 --- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs +++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs @@ -2,8 +2,10 @@ fn main() { unsafe { - dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - //~| NOTE while parsing this parenthesized list of type arguments starting here + dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR `Trait(...)` syntax does not support named parameters + //~^ ERROR cannot find function `dealloc` in this scope [E0425] + //~| ERROR cannot find value `ptr2` in this scope [E0425] + //~| ERROR the `!` type is experimental [E0658] + //~| ERROR cannot find function, tuple struct or tuple variant `Layout` in this scope [E0425] } } diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr index c12bf7f9e3f0..a083883af219 100644 --- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr +++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr @@ -1,16 +1,43 @@ -error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33 +error: `Trait(...)` syntax does not support named parameters + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32 | LL | dealloc(ptr2, Layout::(x: !)(1, 1)); - | --- ^ expected one of 7 possible tokens - | | - | while parsing this parenthesized list of type arguments starting here + | ^ help: remove the parameter name -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43 +error[E0425]: cannot find function `dealloc` in this scope + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9 | LL | dealloc(ptr2, Layout::(x: !)(1, 1)); - | ^ expected one of `.`, `;`, `?`, `}`, or an operator + | ^^^^^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::alloc::dealloc; + | -error: aborting due to 2 previous errors +error[E0425]: cannot find value `ptr2` in this scope + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:17 + | +LL | dealloc(ptr2, Layout::(x: !)(1, 1)); + | ^^^^ not found in this scope +error[E0658]: the `!` type is experimental + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:35 + | +LL | dealloc(ptr2, Layout::(x: !)(1, 1)); + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` 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[E0425]: cannot find function, tuple struct or tuple variant `Layout` in this scope + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:23 + | +LL | dealloc(ptr2, Layout::(x: !)(1, 1)); + | ^^^^^^ not found in this scope + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0425, E0658. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs index 1c28c0632fa8..60dd88e65400 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -2,7 +2,4 @@ struct Apple((Apple, Option(Banana ? Citron))); //~^ ERROR invalid `?` in type -//~| ERROR expected one of `)` or `,`, found `Citron` -//~| ERROR cannot find type `Citron` in this scope [E0412] -//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] -//~| ERROR `Apple` has infinite size +//~| ERROR unexpected token: `Citron` diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr index 97a73b4fd5ed..c92535c3906b 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -10,44 +10,11 @@ LL - struct Apple((Apple, Option(Banana ? Citron))); LL + struct Apple((Apple, Option(Option Citron))); | -error: expected one of `)` or `,`, found `Citron` +error: unexpected token: `Citron` --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 | LL | struct Apple((Apple, Option(Banana ? Citron))); - | -^^^^^^ expected one of `)` or `,` - | | - | help: missing `,` + | ^^^^^^ unexpected token after this -error[E0412]: cannot find type `Citron` in this scope - --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 - | -LL | struct Apple((Apple, Option(Banana ? Citron))); - | ^^^^^^ not found in this scope +error: aborting due to 2 previous errors -error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22 - | -LL | struct Apple((Apple, Option(Banana ? Citron))); - | ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses - | -help: use angle brackets instead - | -LL - struct Apple((Apple, Option(Banana ? Citron))); -LL + struct Apple((Apple, Option)); - | - -error[E0072]: recursive type `Apple` has infinite size - --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1 - | -LL | struct Apple((Apple, Option(Banana ? Citron))); - | ^^^^^^^^^^^^ ----- recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -LL | struct Apple((Box, Option(Banana ? Citron))); - | ++++ + - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0072, E0214, E0412. -For more information about an error, try `rustc --explain E0072`. From bd88f3e3e3eefd781d5cc1f4fbc0630f50e70882 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 7 May 2025 17:31:42 +0800 Subject: [PATCH 219/262] Check `&` before suggest remove deref when trait_selection Signed-off-by: xizheyin --- .../src/error_reporting/traits/suggestions.rs | 6 ++++++ tests/ui/traits/suggest-remove-deref-issue-140166.stderr | 6 +----- 2 files changed, 7 insertions(+), 5 deletions(-) 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 de251ae2893c..8801397b7754 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1516,6 +1516,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { expr.span.with_hi(expr.span.lo() + BytePos(1)) }; + + match self.tcx.sess.source_map().span_to_snippet(span) { + Ok(snippet) if snippet.starts_with("&") => {} + _ => break 'outer, + } + suggestions.push((span, String::new())); let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else { diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.stderr b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr index 8bdcf5981a50..90f24d86d53e 100644 --- a/tests/ui/traits/suggest-remove-deref-issue-140166.stderr +++ b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr @@ -6,6 +6,7 @@ LL | format_args!("{:?}", FlatMap(&Chars)); | | | required by a bound introduced by this call | + = help: the trait `Trait` is implemented for `Chars` note: required for `FlatMap<&Chars>` to implement `Debug` --> $DIR/suggest-remove-deref-issue-140166.rs:7:16 | @@ -15,11 +16,6 @@ LL | impl std::fmt::Debug for FlatMap { | unsatisfied trait bound introduced here note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL -help: consider removing the leading `&`-reference - | -LL - format_args!("{:?}", FlatMap(&Chars)); -LL + format_args!("{:?}", latMap(&Chars)); - | error: aborting due to 1 previous error From df13f7c1fad2c7be5037c9dc2813e926720360e3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 23 Apr 2025 16:03:55 +0000 Subject: [PATCH 220/262] Require T: TypeFoldable in Binder visit --- compiler/rustc_borrowck/src/type_check/opaque_types.rs | 4 ---- compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs | 6 +++--- compiler/rustc_infer/src/infer/outlives/for_liveness.rs | 4 ---- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 5 +++-- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/visit.rs | 4 ++-- .../rustc_trait_selection/src/traits/query/normalize.rs | 4 ++-- compiler/rustc_ty_utils/src/ty.rs | 5 +++-- compiler/rustc_type_ir/src/binder.rs | 6 +++--- compiler/rustc_type_ir/src/ty_kind/closure.rs | 2 +- compiler/rustc_type_ir/src/visit.rs | 8 ++++---- src/tools/clippy/clippy_utils/src/ty/mod.rs | 6 +++--- 12 files changed, 25 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs index d41cbf757d7f..341c50c37f6d 100644 --- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs +++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs @@ -266,10 +266,6 @@ impl<'tcx, OP> TypeVisitor> for ConstrainOpaqueTypeRegionVisitor<'t where OP: FnMut(ty::Region<'tcx>), { - fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { - t.super_visit_with(self); - } - fn visit_region(&mut self, r: ty::Region<'tcx>) { match r.kind() { // ignore bound regions, keep visiting 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 bf91eb1b8fda..4419d5dc7d66 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -9,8 +9,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{AmbigArg, HirId}; use rustc_middle::bug; use rustc_middle::ty::{ - self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, Upcast, + self as ty, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, Upcast, }; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::traits; @@ -996,7 +996,7 @@ struct GenericParamAndBoundVarCollector<'a, 'tcx> { impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'_, 'tcx> { type Result = ControlFlow; - fn visit_binder>>( + fn visit_binder>>( &mut self, binder: &ty::Binder<'tcx, T>, ) -> Self::Result { diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index c44d9723f29d..2a4b9776f68c 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -24,10 +24,6 @@ impl<'tcx, OP> TypeVisitor> for FreeRegionsVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { - fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { - t.super_visit_with(self); - } - fn visit_region(&mut self, r: ty::Region<'tcx>) { match r.kind() { // ignore bound regions, keep visiting diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 7f4789ad0d9b..a8f45d043be9 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -15,7 +15,8 @@ use rustc_middle::ty::relate::{ Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys, }; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + TypeVisitor, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::FutureIncompatibilityReason; @@ -209,7 +210,7 @@ where VarFn: FnOnce() -> FxHashMap, OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>, { - fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { + fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { // When we get into a binder, we need to add its own bound vars to the scope. let mut added = vec![]; for arg in t.bound_vars() { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bc1423a9e3c2..0250c777faf7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2934,7 +2934,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { fn prepare_region_info(&mut self, value: &ty::Binder<'tcx, T>) where - T: TypeVisitable>, + T: TypeFoldable>, { struct RegionNameCollector<'tcx> { used_region_names: FxHashSet, diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 3853a804a920..f80421745991 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -66,7 +66,7 @@ impl<'tcx> TyCtxt<'tcx> { { type Result = ControlFlow<()>; - fn visit_binder>>( + fn visit_binder>>( &mut self, t: &Binder<'tcx, T>, ) -> Self::Result { @@ -168,7 +168,7 @@ impl LateBoundRegionsCollector { } impl<'tcx> TypeVisitor> for LateBoundRegionsCollector { - fn visit_binder>>(&mut self, t: &Binder<'tcx, T>) { + fn visit_binder>>(&mut self, t: &Binder<'tcx, T>) { self.current_index.shift_in(1); t.super_visit_with(self); self.current_index.shift_out(1); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a54eb80fedc2..eb34cb10c68d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -9,7 +9,7 @@ use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::{ self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + TypeVisitableExt, TypeVisitor, TypingMode, }; use rustc_span::DUMMY_SP; use tracing::{debug, info, instrument}; @@ -127,7 +127,7 @@ struct MaxEscapingBoundVarVisitor { } impl<'tcx> TypeVisitor> for MaxEscapingBoundVarVisitor { - fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { + fn visit_binder>>(&mut self, t: &ty::Binder<'tcx, T>) { self.outer_index.shift_in(1); t.super_visit_with(self); self.outer_index.shift_out(1); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 31d69eef5ecf..0c49ddff39bc 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -7,7 +7,8 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions, + self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, + fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; @@ -185,7 +186,7 @@ struct ImplTraitInTraitFinder<'a, 'tcx> { } impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { - fn visit_binder>>(&mut self, binder: &ty::Binder<'tcx, T>) { + fn visit_binder>>(&mut self, binder: &ty::Binder<'tcx, T>) { self.depth.shift_in(1); binder.super_visit_with(self); self.depth.shift_out(1); diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 27ea4e211fef..000cf1e1fd8b 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -128,7 +128,7 @@ impl> TypeFoldable for Binder { } } -impl> TypeVisitable for Binder { +impl> TypeVisitable for Binder { fn visit_with>(&self, visitor: &mut V) -> V::Result { visitor.visit_binder(self) } @@ -147,7 +147,7 @@ impl> TypeSuperFoldable for Binder { } } -impl> TypeSuperVisitable for Binder { +impl> TypeSuperVisitable for Binder { fn super_visit_with>(&self, visitor: &mut V) -> V::Result { self.as_ref().skip_binder().visit_with(visitor) } @@ -292,7 +292,7 @@ impl ValidateBoundVars { impl TypeVisitor for ValidateBoundVars { type Result = ControlFlow<()>; - fn visit_binder>(&mut self, t: &Binder) -> Self::Result { + fn visit_binder>(&mut self, t: &Binder) -> Self::Result { self.binder_index.shift_in(1); let result = t.super_visit_with(self); self.binder_index.shift_out(1); diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index d1ca9bdb7fbd..8ba985d2d193 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -342,7 +342,7 @@ struct HasRegionsBoundAt { // FIXME: Could be optimized to not walk into components with no escaping bound vars. impl TypeVisitor for HasRegionsBoundAt { type Result = ControlFlow<()>; - fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { self.binder.shift_in(1); t.super_visit_with(self)?; self.binder.shift_out(1); diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 2285e0e75de0..ccb84e259112 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, TypeFlags}; +use crate::{self as ty, Interner, TypeFlags, TypeFoldable}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -94,7 +94,7 @@ pub trait TypeVisitor: Sized { #[cfg(not(feature = "nightly"))] type Result: VisitorResult; - fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { t.super_visit_with(self) } @@ -401,7 +401,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor { impl TypeVisitor for HasTypeFlagsVisitor { type Result = ControlFlow; - fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { // If we're looking for the HAS_BINDER_VARS flag, check if the // binder has vars. This won't be present in the binder's bound // value, so we need to check here too. @@ -510,7 +510,7 @@ struct HasEscapingVarsVisitor { impl TypeVisitor for HasEscapingVarsVisitor { type Result = ControlFlow; - fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { self.outer_index.shift_in(1); let result = t.super_visit_with(self); self.outer_index.shift_out(1); diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 8db9cd593b33..da09edd7f7c0 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -20,8 +20,8 @@ use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef, - GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, + GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; @@ -915,7 +915,7 @@ pub fn for_each_top_level_late_bound_region( ControlFlow::Continue(()) } } - fn visit_binder>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result { + fn visit_binder>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result { self.index += 1; let res = t.super_visit_with(self); self.index -= 1; From 1f774d74b3858154564f8f1609c21f618ba28d96 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 May 2025 20:24:23 +0000 Subject: [PATCH 221/262] Only prefer param-env candidates if they remain non-global after norm --- .../src/solve/assembly/mod.rs | 164 +++++++++++++++--- .../src/solve/effect_goals.rs | 47 ++--- .../src/solve/eval_ctxt/mod.rs | 8 + .../src/solve/normalizes_to/mod.rs | 66 +++---- .../src/solve/trait_goals.rs | 83 ++++----- compiler/rustc_type_ir/src/solve/mod.rs | 10 +- .../global-param-env-after-norm.rs | 15 ++ .../normalize-param-env-4.next.stderr | 20 +-- 8 files changed, 268 insertions(+), 145 deletions(-) create mode 100644 tests/ui/traits/next-solver/global-param-env-after-norm.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 101129a231e7..0cc46a0670e4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -2,21 +2,24 @@ pub(super) mod structural_traits; +use std::ops::ControlFlow; + use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::{ - self as ty, Interner, TypeFoldable, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, + self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, + TypeVisitor, TypingMode, Upcast as _, elaborate, }; use tracing::{debug, instrument}; -use super::has_only_region_constraints; use super::trait_goals::TraitGoalProvenVia; +use super::{has_only_region_constraints, inspect}; use crate::delegate::SolverDelegate; use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource, - MaybeCause, NoSolution, QueryResult, + MaybeCause, NoSolution, ParamEnvSource, QueryResult, }; enum AliasBoundKind { @@ -49,18 +52,6 @@ where fn trait_def_id(self, cx: I) -> I::DefId; - /// Try equating an assumption predicate against a goal's predicate. If it - /// holds, then execute the `then` callback, which should do any additional - /// work, then produce a response (typically by executing - /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]). - fn probe_and_match_goal_against_assumption( - ecx: &mut EvalCtxt<'_, D>, - source: CandidateSource, - goal: Goal, - assumption: I::Clause, - then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, - ) -> Result, NoSolution>; - /// Consider a clause, which consists of a "assumption" and some "requirements", /// to satisfy a goal. If the requirements hold, then attempt to satisfy our /// goal by equating it with the assumption. @@ -119,6 +110,67 @@ where alias_ty: ty::AliasTy, ) -> Vec>; + fn probe_and_consider_param_env_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result, NoSolution> { + Self::fast_reject_assumption(ecx, goal, assumption)?; + + ecx.probe(|candidate: &Result, NoSolution>| match candidate { + Ok(candidate) => inspect::ProbeKind::TraitCandidate { + source: candidate.source, + result: Ok(candidate.result), + }, + Err(NoSolution) => inspect::ProbeKind::TraitCandidate { + source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + result: Err(NoSolution), + }, + }) + .enter(|ecx| { + Self::match_assumption(ecx, goal, assumption)?; + let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?; + Ok(Candidate { + source, + result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?, + }) + }) + } + + /// Try equating an assumption predicate against a goal's predicate. If it + /// holds, then execute the `then` callback, which should do any additional + /// work, then produce a response (typically by executing + /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]). + fn probe_and_match_goal_against_assumption( + ecx: &mut EvalCtxt<'_, D>, + source: CandidateSource, + goal: Goal, + assumption: I::Clause, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, + ) -> Result, NoSolution> { + Self::fast_reject_assumption(ecx, goal, assumption)?; + + ecx.probe_trait_candidate(source).enter(|ecx| { + Self::match_assumption(ecx, goal, assumption)?; + then(ecx) + }) + } + + /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`] + /// and [`I::DefId`]. + fn fast_reject_assumption( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result<(), NoSolution>; + + /// Relate the goal and assumption. + fn match_assumption( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result<(), NoSolution>; + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, @@ -500,14 +552,8 @@ where goal: Goal, candidates: &mut Vec>, ) { - for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { - candidates.extend(G::probe_and_consider_implied_clause( - self, - CandidateSource::ParamEnv(i), - goal, - assumption, - [], - )); + for assumption in goal.param_env.caller_bounds().iter() { + candidates.extend(G::probe_and_consider_param_env_candidate(self, goal, assumption)); } } @@ -943,4 +989,76 @@ where } } } + + fn characterize_param_env_assumption( + &mut self, + param_env: I::ParamEnv, + assumption: I::Clause, + ) -> Result, NoSolution> { + // FIXME: + if assumption.has_bound_vars() { + return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)); + } + + match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env }) { + ControlFlow::Break(Err(NoSolution)) => Err(NoSolution), + ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)), + ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)), + } + } +} + +struct FindParamInClause<'a, 'b, D: SolverDelegate, I: Interner> { + ecx: &'a mut EvalCtxt<'b, D>, + param_env: I::ParamEnv, +} + +impl TypeVisitor for FindParamInClause<'_, '_, D, I> +where + D: SolverDelegate, + I: Interner, +{ + type Result = ControlFlow>; + + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + self.ecx.enter_forall(t.clone(), |ecx, v| { + v.visit_with(&mut FindParamInClause { ecx, param_env: self.param_env }) + }) + } + + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else { + return ControlFlow::Break(Err(NoSolution)); + }; + let ty = self.ecx.eager_resolve(ty); + + if let ty::Placeholder(_) = ty.kind() { + ControlFlow::Break(Ok(())) + } else { + ty.super_visit_with(self) + } + } + + fn visit_const(&mut self, ct: I::Const) -> Self::Result { + let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else { + return ControlFlow::Break(Err(NoSolution)); + }; + let ct = self.ecx.eager_resolve(ct); + + if let ty::ConstKind::Placeholder(_) = ct.kind() { + ControlFlow::Break(Ok(())) + } else { + ct.super_visit_with(self) + } + } + + fn visit_region(&mut self, r: I::Region) -> Self::Result { + match r.kind() { + ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()), + ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())), + ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => { + unreachable!() + } + } + } } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 5edc777262b8..ab0ba1005530 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -36,39 +36,40 @@ where self.def_id() } - fn probe_and_match_goal_against_assumption( + fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, - source: rustc_type_ir::solve::CandidateSource, goal: Goal, - assumption: ::Clause, - then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, - ) -> Result, NoSolution> { + assumption: I::Clause, + ) -> Result<(), NoSolution> { if let Some(host_clause) = assumption.as_host_effect_clause() { if host_clause.def_id() == goal.predicate.def_id() && host_clause.constness().satisfies(goal.predicate.constness) { - if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( + if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, host_clause.skip_binder().trait_ref.args, ) { - return Err(NoSolution); + return Ok(()); } - - ecx.probe_trait_candidate(source).enter(|ecx| { - let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); - ecx.eq( - goal.param_env, - goal.predicate.trait_ref, - assumption_trait_pred.trait_ref, - )?; - then(ecx) - }) - } else { - Err(NoSolution) } - } else { - Err(NoSolution) } + + Err(NoSolution) + } + + fn match_assumption( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result<(), NoSolution> { + let Some(host_clause) = assumption.as_host_effect_clause() else { + panic!("fast_reject_assumption should have avoided this"); + }; + + let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); + ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?; + + Ok(()) } /// Register additional assumptions for aliases corresponding to `~const` item bounds. @@ -124,7 +125,7 @@ where fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, - impl_def_id: ::DefId, + impl_def_id: I::DefId, ) -> Result, NoSolution> { let cx = ecx.cx(); @@ -178,7 +179,7 @@ where fn consider_error_guaranteed_candidate( ecx: &mut EvalCtxt<'_, D>, - _guar: ::ErrorGuaranteed, + _guar: I::ErrorGuaranteed, ) -> Result, NoSolution> { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c13e73080550..4a9daad1746f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -19,6 +19,7 @@ use tracing::{debug, instrument, trace}; use super::has_only_region_constraints; use crate::coherence; use crate::delegate::SolverDelegate; +use crate::resolve::EagerResolver; use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::search_graph::SearchGraph; use crate::solve::{ @@ -1000,6 +1001,13 @@ where self.delegate.resolve_vars_if_possible(value) } + pub(super) fn eager_resolve(&self, value: T) -> T + where + T: TypeFoldable, + { + value.fold_with(&mut EagerResolver::new(self.delegate)) + } + pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs { let args = self.delegate.fresh_args_for_item(def_id); for arg in args.iter() { 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 400b4ce1200c..9c17a15bb0e1 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 @@ -106,50 +106,50 @@ where self.trait_def_id(cx) } - fn probe_and_match_goal_against_assumption( + fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, - source: CandidateSource, goal: Goal, assumption: I::Clause, - then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, - ) -> Result, NoSolution> { + ) -> Result<(), NoSolution> { if let Some(projection_pred) = assumption.as_projection_clause() { if projection_pred.item_def_id() == goal.predicate.def_id() { - let cx = ecx.cx(); - if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( + if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.alias.args, projection_pred.skip_binder().projection_term.args, ) { - return Err(NoSolution); + return Ok(()); } - ecx.probe_trait_candidate(source).enter(|ecx| { - let assumption_projection_pred = - ecx.instantiate_binder_with_infer(projection_pred); - ecx.eq( - goal.param_env, - goal.predicate.alias, - assumption_projection_pred.projection_term, - )?; - - ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); - - // 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::AliasWellFormed, - cx.own_predicates_of(goal.predicate.def_id()) - .iter_instantiated(cx, goal.predicate.alias.args) - .map(|pred| goal.with(cx, pred)), - ); - - then(ecx) - }) - } else { - Err(NoSolution) } - } else { - Err(NoSolution) } + + Err(NoSolution) + } + + fn match_assumption( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result<(), NoSolution> { + let Some(projection_pred) = assumption.as_projection_clause() else { + panic!("fast_reject_assumption should have avoided this"); + }; + + let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred); + ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?; + + ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); + + // Add GAT where clauses from the trait's definition + // FIXME: We don't need these, since these are the type's own WF obligations. + let cx = ecx.cx(); + ecx.add_goals( + GoalSource::AliasWellFormed, + cx.own_predicates_of(goal.predicate.def_id()) + .iter_instantiated(cx, goal.predicate.alias.args) + .map(|pred| goal.with(cx, pred)), + ); + + Ok(()) } fn consider_additional_alias_assumptions( diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index d19249df387c..4d42bb137f0b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - NoSolution, QueryResult, + NoSolution, ParamEnvSource, }; impl assembly::GoalKind for TraitPredicate @@ -125,39 +125,40 @@ where .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } - fn probe_and_match_goal_against_assumption( + fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, - source: CandidateSource, goal: Goal, assumption: I::Clause, - then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, - ) -> Result, NoSolution> { + ) -> Result<(), NoSolution> { if let Some(trait_clause) = assumption.as_trait_clause() { if trait_clause.def_id() == goal.predicate.def_id() && trait_clause.polarity() == goal.predicate.polarity { - if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( + if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, trait_clause.skip_binder().trait_ref.args, ) { - return Err(NoSolution); + return Ok(()); } - - ecx.probe_trait_candidate(source).enter(|ecx| { - let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); - ecx.eq( - goal.param_env, - goal.predicate.trait_ref, - assumption_trait_pred.trait_ref, - )?; - then(ecx) - }) - } else { - Err(NoSolution) } - } else { - Err(NoSolution) } + + Err(NoSolution) + } + + fn match_assumption( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + assumption: I::Clause, + ) -> Result<(), NoSolution> { + let Some(trait_clause) = assumption.as_trait_clause() else { + panic!("fast_reject_assumption should have avoided this"); + }; + + let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); + ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?; + + Ok(()) } fn consider_auto_trait_candidate( @@ -1253,10 +1254,9 @@ where D: SolverDelegate, I: Interner, { - #[instrument(level = "debug", skip(self, goal), ret)] + #[instrument(level = "debug", skip(self), ret)] pub(super) fn merge_trait_candidates( &mut self, - goal: Goal>, mut candidates: Vec>, ) -> Result<(CanonicalResponse, Option), NoSolution> { if let TypingMode::Coherence = self.typing_mode() { @@ -1284,21 +1284,9 @@ where // If there are non-global where-bounds, prefer where-bounds // (including global ones) over everything else. - let has_non_global_where_bounds = candidates.iter().any(|c| match c.source { - CandidateSource::ParamEnv(idx) => { - let where_bound = goal.param_env.caller_bounds().get(idx).unwrap(); - let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else { - unreachable!("expected trait-bound: {where_bound:?}"); - }; - - if trait_pred.has_bound_vars() || !trait_pred.is_global() { - return true; - } - - false - } - _ => false, - }); + let has_non_global_where_bounds = candidates + .iter() + .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal))); if has_non_global_where_bounds { let where_bounds: Vec<_> = candidates .iter() @@ -1331,13 +1319,16 @@ where // is still reported as being proven-via the param-env so that rigid projections // operate correctly. Otherwise, drop all global where-bounds before merging the // remaining candidates. - let proven_via = - if candidates.iter().all(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { - TraitGoalProvenVia::ParamEnv - } else { - candidates.retain(|c| !matches!(c.source, CandidateSource::ParamEnv(_))); - TraitGoalProvenVia::Misc - }; + let proven_via = if candidates + .iter() + .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global))) + { + TraitGoalProvenVia::ParamEnv + } else { + candidates + .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global))); + TraitGoalProvenVia::Misc + }; let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); if let Some(response) = self.try_merge_responses(&all_candidates) { @@ -1353,7 +1344,7 @@ where goal: Goal>, ) -> Result<(CanonicalResponse, Option), NoSolution> { let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All); - self.merge_trait_candidates(goal, candidates) + self.merge_trait_candidates(candidates) } fn try_stall_coroutine_witness( diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 4e9b87fdf74d..994ec2b341dc 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -160,7 +160,7 @@ pub enum CandidateSource { /// (x.clone(), x) /// } /// ``` - ParamEnv(usize), + ParamEnv(ParamEnvSource), /// If the self type is an alias type, e.g. an opaque type or a projection, /// we know the bounds on that alias to hold even without knowing its concrete /// underlying type. @@ -189,6 +189,14 @@ pub enum CandidateSource { CoherenceUnknowable, } +#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] +pub enum ParamEnvSource { + /// Preferred eagerly. + NonGlobal, + // Not considered unless there are non-global param-env candidates too. + Global, +} + #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] #[cfg_attr( feature = "nightly", diff --git a/tests/ui/traits/next-solver/global-param-env-after-norm.rs b/tests/ui/traits/next-solver/global-param-env-after-norm.rs new file mode 100644 index 000000000000..0d098db67d36 --- /dev/null +++ b/tests/ui/traits/next-solver/global-param-env-after-norm.rs @@ -0,0 +1,15 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +struct NewSolver; +struct OldSolver; + +fn foo() +where + T: Iterator, + OldSolver: Into, +{ + let x: OldSolver = OldSolver.into(); +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index e91a48f62aec..f5fd9ce9864c 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,24 +4,6 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` LL | ::Assoc: Trait, | ^^^^^ -error[E0275]: overflow evaluating the requirement `::Assoc well-formed` - --> $DIR/normalize-param-env-4.rs:19:26 - | -LL | ::Assoc: Trait, - | ^^^^^ - -error[E0275]: overflow evaluating the requirement `T: Trait` - --> $DIR/normalize-param-env-4.rs:32:19 - | -LL | impls_trait::(); - | ^ - | -note: required by a bound in `impls_trait` - --> $DIR/normalize-param-env-4.rs:15:19 - | -LL | fn impls_trait() {} - | ^^^^^ required by this bound in `impls_trait` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0275`. From 8a21d1b495556554dc4ee55338423870b4f7dd53 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 May 2025 16:27:48 +0000 Subject: [PATCH 222/262] Review --- .../src/solve/assembly/mod.rs | 24 ++++++++++++++----- .../src/solve/effect_goals.rs | 4 +--- .../src/solve/eval_ctxt/mod.rs | 12 +++++----- .../src/solve/normalizes_to/mod.rs | 4 +--- .../src/solve/trait_goals.rs | 4 +--- compiler/rustc_type_ir/src/solve/mod.rs | 5 ++-- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 0cc46a0670e4..345a272895d3 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -123,7 +123,7 @@ where result: Ok(candidate.result), }, Err(NoSolution) => inspect::ProbeKind::TraitCandidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + source: CandidateSource::ParamEnv(ParamEnvSource::Global), result: Err(NoSolution), }, }) @@ -157,7 +157,7 @@ where } /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`] - /// and [`I::DefId`]. + /// and `DefId`. fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, goal: Goal, @@ -990,12 +990,26 @@ where } } + /// Compute whether a param-env assumption is global or non-global after normalizing it. + /// + /// This is necessary because, for example, given: + /// + /// ```ignore,rust + /// where + /// T: Trait, + /// i32: From, + /// ``` + /// + /// The `i32: From` bound is non-global before normalization, but is global after. + /// Since the old trait solver normalized param-envs eagerly, we want to emulate this + /// behavior lazily. fn characterize_param_env_assumption( &mut self, param_env: I::ParamEnv, assumption: I::Clause, ) -> Result, NoSolution> { - // FIXME: + // FIXME: This should be fixed, but it also requires changing the behavior + // in the old solver which is currently relied on. if assumption.has_bound_vars() { return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)); } @@ -1030,7 +1044,6 @@ where let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else { return ControlFlow::Break(Err(NoSolution)); }; - let ty = self.ecx.eager_resolve(ty); if let ty::Placeholder(_) = ty.kind() { ControlFlow::Break(Ok(())) @@ -1043,7 +1056,6 @@ where let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else { return ControlFlow::Break(Err(NoSolution)); }; - let ct = self.ecx.eager_resolve(ct); if let ty::ConstKind::Placeholder(_) = ct.kind() { ControlFlow::Break(Ok(())) @@ -1053,7 +1065,7 @@ where } fn visit_region(&mut self, r: I::Region) -> Self::Result { - match r.kind() { + match self.ecx.eager_resolve_region(r).kind() { ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()), ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())), ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => { diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index ab0ba1005530..84a83d79cf04 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -62,9 +62,7 @@ where goal: Goal, assumption: I::Clause, ) -> Result<(), NoSolution> { - let Some(host_clause) = assumption.as_host_effect_clause() else { - panic!("fast_reject_assumption should have avoided this"); - }; + let host_clause = assumption.as_host_effect_clause().unwrap(); let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 4a9daad1746f..bf9f21d05f6c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -19,7 +19,6 @@ use tracing::{debug, instrument, trace}; use super::has_only_region_constraints; use crate::coherence; use crate::delegate::SolverDelegate; -use crate::resolve::EagerResolver; use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::search_graph::SearchGraph; use crate::solve::{ @@ -1001,11 +1000,12 @@ where self.delegate.resolve_vars_if_possible(value) } - pub(super) fn eager_resolve(&self, value: T) -> T - where - T: TypeFoldable, - { - value.fold_with(&mut EagerResolver::new(self.delegate)) + pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region { + if let ty::ReVar(vid) = r.kind() { + self.delegate.opportunistic_resolve_lt_var(vid) + } else { + r + } } pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs { 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 9c17a15bb0e1..b90e34e78101 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 @@ -130,9 +130,7 @@ where goal: Goal, assumption: I::Clause, ) -> Result<(), NoSolution> { - let Some(projection_pred) = assumption.as_projection_clause() else { - panic!("fast_reject_assumption should have avoided this"); - }; + let projection_pred = assumption.as_projection_clause().unwrap(); let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred); ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 4d42bb137f0b..e3addf8bf93f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -151,9 +151,7 @@ where goal: Goal, assumption: I::Clause, ) -> Result<(), NoSolution> { - let Some(trait_clause) = assumption.as_trait_clause() else { - panic!("fast_reject_assumption should have avoided this"); - }; + let trait_clause = assumption.as_trait_clause().unwrap(); let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?; diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 994ec2b341dc..e45a7b7fbc16 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -147,9 +147,8 @@ pub enum CandidateSource { /// For a list of all traits with builtin impls, check out the /// `EvalCtxt::assemble_builtin_impl_candidates` method. BuiltinImpl(BuiltinImplSource), - /// An assumption from the environment. - /// - /// More precisely we've used the `n-th` assumption in the `param_env`. + /// An assumption from the environment. Stores a [`ParamEnvSource`], since we + /// prefer non-global param-env candidates in candidate assembly. /// /// ## Examples /// From fd37906477d36968247ddf2db43244af5d54b752 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 May 2025 19:44:10 +0000 Subject: [PATCH 223/262] Only include associated type bounds for Self:Sized associated types if they are provided --- .../src/hir_ty_lowering/dyn_compatibility.rs | 9 +++---- compiler/rustc_middle/src/ty/sty.rs | 5 +++- .../object/constrain-via-unnecessary-bound.rs | 24 +++++++++++++++++++ .../constrain-via-unnecessary-bound.stderr | 19 +++++++++++++++ tests/ui/traits/object/pretty.stderr | 6 ++--- 5 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 tests/ui/traits/object/constrain-via-unnecessary-bound.rs create mode 100644 tests/ui/traits/object/constrain-via-unnecessary-bound.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 88f745892048..389b59bbcb47 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -204,9 +204,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .filter(|item| item.is_type()) // No RPITITs -- they're not dyn-compatible for now. .filter(|item| !item.is_impl_trait_in_trait()) - // If the associated type has a `where Self: Sized` bound, - // we do not need to constrain the associated type. - .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .map(|item| (item.def_id, trait_ref)), ); } @@ -285,7 +282,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Some(assoc) = projection_bounds.get(&key) { Some(*assoc) } else { - missing_assoc_types.insert(key); + // If the associated type has a `where Self: Sized` bound, + // we do not need to constrain the associated type. + if !tcx.generics_require_sized_self(key.0) { + missing_assoc_types.insert(key); + } None } }) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2165cf186bd5..c31ce1bc6307 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -723,7 +723,10 @@ impl<'tcx> Ty<'tcx> { repr: DynKind, ) -> Ty<'tcx> { if cfg!(debug_assertions) { - let projection_count = obj.projection_bounds().count(); + let projection_count = obj + .projection_bounds() + .filter(|item| !tcx.generics_require_sized_self(item.item_def_id())) + .count(); let expected_count: usize = obj .principal_def_id() .into_iter() diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs new file mode 100644 index 000000000000..5534471fb27f --- /dev/null +++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs @@ -0,0 +1,24 @@ +//@ check-pass + +// Regression test for . +// Test that we lower impossible-to-satisfy associated type bounds, which +// may for example constrain impl parameters. + +pub trait Other {} + +pub trait Trait { + type Assoc + where + Self: Sized; +} + +impl Other for dyn Trait {} +// `dyn Trait` is a different "nominal type" than `dyn Traiat`. +impl Other for dyn Trait {} +//~^ WARN unnecessary associated type bound for dyn-incompatible associated type + +// I hope it's clear that `dyn Trait` (w/o `Assoc`) wouldn't match this impl. +impl dyn Trait {} +//~^ WARN unnecessary associated type bound for dyn-incompatible associated type + +fn main() {} diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr new file mode 100644 index 000000000000..4383ca869eac --- /dev/null +++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr @@ -0,0 +1,19 @@ +warning: unnecessary associated type bound for dyn-incompatible associated type + --> $DIR/constrain-via-unnecessary-bound.rs:17:26 + | +LL | impl Other for dyn Trait {} + | ^^^^^^^^^^ help: remove this bound + | + = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized` + = note: `#[warn(unused_associated_type_bounds)]` on by default + +warning: unnecessary associated type bound for dyn-incompatible associated type + --> $DIR/constrain-via-unnecessary-bound.rs:21:19 + | +LL | impl dyn Trait {} + | ^^^^^^^^^ help: remove this bound + | + = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized` + +warning: 2 warnings emitted + diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr index 37fe142951d8..2f9fdf151f08 100644 --- a/tests/ui/traits/object/pretty.stderr +++ b/tests/ui/traits/object/pretty.stderr @@ -154,12 +154,12 @@ error[E0308]: mismatched types --> $DIR/pretty.rs:41:56 | LL | fn dyn_has_gat(x: &dyn HasGat = ()>) { x } - | - ^ expected `()`, found `&dyn HasGat` + | - ^ expected `()`, found `&dyn HasGat = ()>` | | - | help: try adding a return type: `-> &dyn HasGat` + | help: try adding a return type: `-> &dyn HasGat = ()>` | = note: expected unit type `()` - found reference `&dyn HasGat` + found reference `&dyn HasGat = ()>` error: aborting due to 14 previous errors; 1 warning emitted From a910329c671aea4342413ecd8f88f09e47f8b85a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 May 2025 18:32:44 +0000 Subject: [PATCH 224/262] Use MaybeCause::or to allow constraints from overflows if they are combined with ambiguity --- .../src/solve/eval_ctxt/canonical.rs | 7 ++- .../src/solve/eval_ctxt/mod.rs | 4 +- .../rustc_next_trait_solver/src/solve/mod.rs | 22 ++++---- .../src/solve/fulfill/derive_errors.rs | 8 ++- .../src/solve/inspect/analyse.rs | 2 +- compiler/rustc_type_ir/src/solve/mod.rs | 55 +++++++++++++++--- ...w-plus-ambiguity-normalizes-to-response.rs | 56 +++++++++++++++++++ 7 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 65b10e4f23f0..59e9407c97c4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -132,12 +132,14 @@ where (Certainty::Yes, NestedNormalizationGoals(goals)) } _ => { - let certainty = shallow_certainty.unify_with(goals_certainty); + let certainty = shallow_certainty.and(goals_certainty); (certainty, NestedNormalizationGoals::empty()) } }; - if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty { + if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) = + certainty + { // If we have overflow, it's probable that we're substituting a type // into itself infinitely and any partial substitutions in the query // response are probably not useful anyways, so just return an empty @@ -193,6 +195,7 @@ where debug!(?num_non_region_vars, "too many inference variables -> overflow"); return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow { suggest_increasing_limit: true, + keep_constraints: false, })); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c13e73080550..863826046103 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -666,7 +666,7 @@ where Certainty::Yes => {} Certainty::Maybe(_) => { self.nested_goals.push((source, with_resolved_vars)); - unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty)); + unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty)); } } } else { @@ -680,7 +680,7 @@ where Certainty::Yes => {} Certainty::Maybe(_) => { self.nested_goals.push((source, goal)); - unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty)); + unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty)); } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index c9f4fc649b52..8173146e2fe2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -253,16 +253,18 @@ where } fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse]) -> CanonicalResponse { - debug_assert!(!responses.is_empty()); - if let Certainty::Maybe(maybe_cause) = - responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| { - certainty.unify_with(response.value.certainty) - }) - { - self.make_ambiguous_response_no_constraints(maybe_cause) - } else { - panic!("expected flounder response to be ambiguous") - } + debug_assert!(responses.len() > 1); + let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| { + // Pull down the certainty of `Certainty::Yes` to ambiguity when combining + // these responses, b/c we're combining more than one response and this we + // don't know which one applies. + let candidate = match response.value.certainty { + Certainty::Yes => MaybeCause::Ambiguity, + Certainty::Maybe(candidate) => candidate, + }; + maybe_cause.or(candidate) + }); + self.make_ambiguous_response_no_constraints(maybe_cause) } /// If we fail to merge responses we flounder and return overflow or ambiguity. 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 2d445dd07900..f64cd5ffebe3 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -99,7 +99,13 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>( Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { (FulfillmentErrorCode::Ambiguity { overflow: None }, true) } - Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => ( + Ok(( + _, + Certainty::Maybe(MaybeCause::Overflow { + suggest_increasing_limit, + keep_constraints: _, + }), + )) => ( FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }, // Don't look into overflows because we treat overflows weirdly anyways. // We discard the inference constraints from overflowing goals, so diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 24b87000e32b..9795655e8422 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -382,7 +382,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { if let Some(term_hack) = normalizes_to_term_hack { infcx .probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env)) - .map(|certainty| ok.value.certainty.unify_with(certainty)) + .map(|certainty| ok.value.certainty.and(certainty)) } else { Ok(ok.value.certainty) } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 4e9b87fdf74d..8f84b1553985 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -266,17 +266,17 @@ impl Certainty { /// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar` /// in ambiguity without changing the inference state, we still want to tell the /// user that `T: Baz` results in overflow. - pub fn unify_with(self, other: Certainty) -> Certainty { + pub fn and(self, other: Certainty) -> Certainty { match (self, other) { (Certainty::Yes, Certainty::Yes) => Certainty::Yes, (Certainty::Yes, Certainty::Maybe(_)) => other, (Certainty::Maybe(_), Certainty::Yes) => self, - (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)), + (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)), } } pub const fn overflow(suggest_increasing_limit: bool) -> Certainty { - Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }) + Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false }) } } @@ -289,19 +289,58 @@ pub enum MaybeCause { /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals. Ambiguity, /// We gave up due to an overflow, most often by hitting the recursion limit. - Overflow { suggest_increasing_limit: bool }, + Overflow { suggest_increasing_limit: bool, keep_constraints: bool }, } impl MaybeCause { - fn unify_with(self, other: MaybeCause) -> MaybeCause { + fn and(self, other: MaybeCause) -> MaybeCause { match (self, other) { (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity, (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other, (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self, ( - MaybeCause::Overflow { suggest_increasing_limit: a }, - MaybeCause::Overflow { suggest_increasing_limit: b }, - ) => MaybeCause::Overflow { suggest_increasing_limit: a || b }, + MaybeCause::Overflow { + suggest_increasing_limit: limit_a, + keep_constraints: keep_a, + }, + MaybeCause::Overflow { + suggest_increasing_limit: limit_b, + keep_constraints: keep_b, + }, + ) => MaybeCause::Overflow { + suggest_increasing_limit: limit_a && limit_b, + keep_constraints: keep_a && keep_b, + }, + } + } + + pub fn or(self, other: MaybeCause) -> MaybeCause { + match (self, other) { + (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity, + + // When combining ambiguity + overflow, we can keep constraints. + ( + MaybeCause::Ambiguity, + MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ }, + ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true }, + ( + MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ }, + MaybeCause::Ambiguity, + ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true }, + + ( + MaybeCause::Overflow { + suggest_increasing_limit: limit_a, + keep_constraints: keep_a, + }, + MaybeCause::Overflow { + suggest_increasing_limit: limit_b, + keep_constraints: keep_b, + }, + ) => MaybeCause::Overflow { + suggest_increasing_limit: limit_a || limit_b, + keep_constraints: keep_a || keep_b, + }, } } } diff --git a/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs new file mode 100644 index 000000000000..4b20cd11b0d4 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs @@ -0,0 +1,56 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Regression test for . +// See comment below on `fn main`. + +trait Intersect { + type Output; +} + +impl Intersect> for T +where + T: Intersect, +{ + type Output = T; +} + +impl Intersect for Cuboid { + type Output = Cuboid; +} + +fn intersect(_: &T, _: &U) -> T::Output +where + T: Intersect, +{ + todo!() +} + +struct Cuboid; +impl Cuboid { + fn method(&self) {} +} + +fn main() { + let x = vec![]; + // Here we end up trying to normalize `>>::Output` + // for the return type of the function, to constrain `y`. The impl then requires + // `Cuboid: Intersect`, which has two candidates. One that constrains + // `?0 = Vec`, which itself has the same two candidates and ends up leading + // to a recursion depth overflow. In the second impl, we constrain `?0 = Cuboid`. + // + // Floundering leads to us combining the overflow candidate and yes candidate to + // overflow. Because the response was overflow, we used to bubble it up to the + // parent normalizes-to goal, which caused us to drop its constraint that would + // guide us to normalize the associated type mentioned before. + // + // After this PR, we implement a new floundering "algebra" such that `Overflow OR Maybe` + // returns anew `Overflow { keep_constraints: true }`, which means that we don't + // need to drop constraints in the parent normalizes-to goal. This allows us to + // normalize `y` to `Cuboid`, and allows us to call the method successfully. We + // then constrain the `?0` in `let x: Vec = x` below, so that we don't have + // a left over ambiguous goal. + let y = intersect(&Cuboid, &x); + y.method(); + let x: Vec = x; +} From b27d630f8958374bc774bc183105ee23f5320a3a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 30 Apr 2025 15:38:24 +0000 Subject: [PATCH 225/262] Point out region bound mismatches in check_region_bounds_on_impl_item --- .../src/check/compare_impl_item.rs | 107 +++++++++++------- ...regions-bound-missing-bound-in-impl.stderr | 11 +- tests/ui/error-codes/E0195.rs | 1 + tests/ui/error-codes/E0195.stderr | 5 +- 4 files changed, 79 insertions(+), 45 deletions(-) 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 bbf36fef1ddb..553d981aa38a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1137,65 +1137,88 @@ fn check_region_bounds_on_impl_item<'tcx>( // but found 0" it's confusing, because it looks like there // are zero. Since I don't quite know how to phrase things at // the moment, give a kind of vague error message. - if trait_params != impl_params { - let span = tcx - .hir_get_generics(impl_m.def_id.expect_local()) - .expect("expected impl item to have generics or else we can't compare them") - .span; + if trait_params == impl_params { + return Ok(()); + } - let mut generics_span = None; - let mut bounds_span = vec![]; - let mut where_span = None; - if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id) - && let Some(trait_generics) = trait_node.generics() - { - generics_span = Some(trait_generics.span); - // FIXME: we could potentially look at the impl's bounds to not point at bounds that - // *are* present in the impl. - for p in trait_generics.predicates { - if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { - for b in pred.bounds { + let span = tcx + .hir_get_generics(impl_m.def_id.expect_local()) + .expect("expected impl item to have generics or else we can't compare them") + .span; + + let mut generics_span = None; + let mut bounds_span = vec![]; + let mut where_span = None; + + if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id) + && let Some(trait_generics) = trait_node.generics() + { + generics_span = Some(trait_generics.span); + // FIXME: we could potentially look at the impl's bounds to not point at bounds that + // *are* present in the impl. + for p in trait_generics.predicates { + match p.kind { + hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { + bounds, + .. + }) + | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { + bounds, + .. + }) => { + for b in *bounds { if let hir::GenericBound::Outlives(lt) = b { bounds_span.push(lt.ident.span); } } } + _ => {} } - if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id) - && let Some(impl_generics) = impl_node.generics() - { - let mut impl_bounds = 0; - for p in impl_generics.predicates { - if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { - for b in pred.bounds { + } + if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id) + && let Some(impl_generics) = impl_node.generics() + { + let mut impl_bounds = 0; + for p in impl_generics.predicates { + match p.kind { + hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { + bounds, + .. + }) + | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { + bounds, + .. + }) => { + for b in *bounds { if let hir::GenericBound::Outlives(_) = b { impl_bounds += 1; } } } - } - if impl_bounds == bounds_span.len() { - bounds_span = vec![]; - } else if impl_generics.has_where_clause_predicates { - where_span = Some(impl_generics.where_clause_span); + _ => {} } } + if impl_bounds == bounds_span.len() { + bounds_span = vec![]; + } else if impl_generics.has_where_clause_predicates { + where_span = Some(impl_generics.where_clause_span); + } } - let reported = tcx - .dcx() - .create_err(LifetimesOrBoundsMismatchOnTrait { - span, - item_kind: impl_m.descr(), - ident: impl_m.ident(tcx), - generics_span, - bounds_span, - where_span, - }) - .emit_unless(delay); - return Err(reported); } - Ok(()) + let reported = tcx + .dcx() + .create_err(LifetimesOrBoundsMismatchOnTrait { + span, + item_kind: impl_m.descr(), + ident: impl_m.ident(tcx), + generics_span, + bounds_span, + where_span, + }) + .emit_unless(delay); + + Err(reported) } #[instrument(level = "debug", skip(infcx))] diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 5f0347bdb4d4..2afacd4cc952 100644 --- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -11,7 +11,10 @@ error[E0195]: lifetime parameters or bounds on method `has_bound` do not match t --> $DIR/regions-bound-missing-bound-in-impl.rs:23:17 | LL | fn has_bound<'b:'a>(self, b: Inv<'b>); - | ------- lifetimes in impl do not match this method in trait + | ------- + | | | + | | this bound might be missing in the impl + | lifetimes in impl do not match this method in trait ... LL | fn has_bound<'b>(self, b: Inv<'b>) { | ^^^^ lifetimes do not match method in trait @@ -58,7 +61,11 @@ error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not matc --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20 | LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); - | ---------------- lifetimes in impl do not match this method in trait + | ---------------- + | | | | + | | | this bound might be missing in the impl + | | this bound might be missing in the impl + | lifetimes in impl do not match this method in trait ... LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { | ^ lifetimes do not match method in trait diff --git a/tests/ui/error-codes/E0195.rs b/tests/ui/error-codes/E0195.rs index a7e51dff2f3f..8280901b1cd5 100644 --- a/tests/ui/error-codes/E0195.rs +++ b/tests/ui/error-codes/E0195.rs @@ -8,6 +8,7 @@ struct Foo; impl Trait for Foo { fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195 //~^ NOTE lifetimes do not match associated function in trait + //~| NOTE this bound might be missing in the impl } } diff --git a/tests/ui/error-codes/E0195.stderr b/tests/ui/error-codes/E0195.stderr index 9767dee9aecd..6eac910bedfb 100644 --- a/tests/ui/error-codes/E0195.stderr +++ b/tests/ui/error-codes/E0195.stderr @@ -2,7 +2,10 @@ error[E0195]: lifetime parameters or bounds on associated function `bar` do not --> $DIR/E0195.rs:9:11 | LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); - | ---------- lifetimes in impl do not match this associated function in trait + | ---------- + | | | + | | this bound might be missing in the impl + | lifetimes in impl do not match this associated function in trait ... LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { | ^^^^^^^ lifetimes do not match associated function in trait From 3799d8427ab95a1a72dbc3dde1bf3a992b4fecf5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 May 2025 16:55:21 +0000 Subject: [PATCH 226/262] Review --- .../src/hir_ty_lowering/dyn_compatibility.rs | 25 +++++++++++++++---- .../object/constrain-via-unnecessary-bound.rs | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 389b59bbcb47..f6e5149bd2b1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -172,7 +172,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let principal_trait = regular_traits.into_iter().next(); - let mut needed_associated_types = vec![]; + // A stable ordering of associated types from the principal trait and all its + // supertraits. We use this to ensure that different substitutions of a trait + // don't result in `dyn Trait` types with different projections lists, which + // can be unsound: . + // We achieve a stable ordering by walking over the unsubstituted principal + // trait ref. + let mut ordered_associated_types = vec![]; + if let Some((principal_trait, ref spans)) = principal_trait { let principal_trait = principal_trait.map_bound(|trait_pred| { assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); @@ -197,7 +204,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME(negative_bounds): Handle this correctly... let trait_ref = tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref)); - needed_associated_types.extend( + ordered_associated_types.extend( tcx.associated_items(pred.trait_ref.def_id) .in_definition_order() // We only care about associated types. @@ -275,15 +282,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + // We compute the list of projection bounds taking the ordered associated types, + // and check if there was an entry in the collected `projection_bounds`. Those + // are computed by first taking the user-written associated types, then elaborating + // the principal trait ref, and only using those if there was no user-written. + // See note below about how we handle missing associated types with `Self: Sized`, + // which are not required to be provided, but are still used if they are provided. let mut missing_assoc_types = FxIndexSet::default(); - let projection_bounds: Vec<_> = needed_associated_types + let projection_bounds: Vec<_> = ordered_associated_types .into_iter() .filter_map(|key| { if let Some(assoc) = projection_bounds.get(&key) { Some(*assoc) } else { - // If the associated type has a `where Self: Sized` bound, - // we do not need to constrain the associated type. + // If the associated type has a `where Self: Sized` bound, then + // we do not need to provide the associated type. This results in + // a `dyn Trait` type that has a different number of projection + // bounds, which may lead to type mismatches. if !tcx.generics_require_sized_self(key.0) { missing_assoc_types.insert(key); } diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs index 5534471fb27f..4640d6b3ed59 100644 --- a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs +++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs @@ -13,7 +13,7 @@ pub trait Trait { } impl Other for dyn Trait {} -// `dyn Trait` is a different "nominal type" than `dyn Traiat`. +// `dyn Trait` is a different "nominal type" than `dyn Trait`. impl Other for dyn Trait {} //~^ WARN unnecessary associated type bound for dyn-incompatible associated type From 6dabf7ea3a518a63d273a4d1bcd545ac7d29bd23 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 25 Apr 2025 16:44:58 -0700 Subject: [PATCH 227/262] [Arm64EC] Only decorate functions with `#` --- compiler/rustc_codegen_llvm/src/consts.rs | 7 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 120 +++++++++++++----- .../src/back/symbol_export.rs | 11 +- compiler/rustc_codegen_ssa/src/base.rs | 47 ++++--- compiler/rustc_codegen_ssa/src/lib.rs | 2 +- .../src/middle/exported_symbols.rs | 2 +- compiler/rustc_target/src/spec/base/msvc.rs | 14 +- .../arm64ec-import-export-static/export.rs | 23 ++++ .../arm64ec-import-export-static/import.rs | 12 ++ .../arm64ec-import-export-static/rmake.rs | 15 +++ .../run-make/sanitizer-dylib-link/program.rs | 2 +- 11 files changed, 201 insertions(+), 54 deletions(-) create mode 100644 tests/run-make/arm64ec-import-export-static/export.rs create mode 100644 tests/run-make/arm64ec-import-export-static/import.rs create mode 100644 tests/run-make/arm64ec-import-export-static/rmake.rs diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index bf81eb648f8a..cbac55c71531 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -364,7 +364,12 @@ impl<'ll> CodegenCx<'ll, '_> { if !def_id.is_local() { let needs_dll_storage_attr = self.use_dll_storage_attrs - && !self.tcx.is_foreign_item(def_id) + // If the symbol is a foreign item, then don't automatically apply DLLImport, as + // we'll rely on the #[link] attribute instead. BUT, if this is an internal symbol + // then it may be generated by the compiler in some crate, so we do need to apply + // DLLImport when linking with the MSVC linker. + && (!self.tcx.is_foreign_item(def_id) + || (self.sess().target.is_like_msvc && fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))) // Local definitions can never be imported, so we must not apply // the DLLImport annotation. && !dso_local diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 8fc83908efbc..80ee8ea22288 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -337,7 +337,12 @@ pub(crate) trait Linker { fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]); fn no_crt_objects(&mut self); fn no_default_libraries(&mut self); - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]); + fn export_symbols( + &mut self, + tmpdir: &Path, + crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ); fn subsystem(&mut self, subsystem: &str); fn linker_plugin_lto(&mut self); fn add_eh_frame_header(&mut self) {} @@ -770,7 +775,12 @@ impl<'a> Linker for GccLinker<'a> { } } - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + tmpdir: &Path, + crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { // Symbol visibility in object files typically takes care of this. if crate_type == CrateType::Executable { let should_export_executable_symbols = @@ -799,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> { // Write a plain, newline-separated list of symbols let res: io::Result<()> = try { let mut f = File::create_buffered(&path)?; - for sym in symbols { + for (sym, _) in symbols { debug!(" _{sym}"); writeln!(f, "_{sym}")?; } @@ -814,11 +824,12 @@ impl<'a> Linker for GccLinker<'a> { // .def file similar to MSVC one but without LIBRARY section // because LD doesn't like when it's empty writeln!(f, "EXPORTS")?; - for symbol in symbols { + for (symbol, kind) in symbols { + let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" }; debug!(" _{symbol}"); // Quote the name in case it's reserved by linker in some way // (this accounts for names with dots in particular). - writeln!(f, " \"{symbol}\"")?; + writeln!(f, " \"{symbol}\"{kind_marker}")?; } }; if let Err(error) = res { @@ -831,7 +842,7 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, "{{")?; if !symbols.is_empty() { writeln!(f, " global:")?; - for sym in symbols { + for (sym, _) in symbols { debug!(" {sym};"); writeln!(f, " {sym};")?; } @@ -1098,7 +1109,12 @@ impl<'a> Linker for MsvcLinker<'a> { // crates. Upstream rlibs may be linked statically to this dynamic library, // in which case they may continue to transitively be used and hence need // their symbols exported. - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + tmpdir: &Path, + crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { // Symbol visibility takes care of this typically if crate_type == CrateType::Executable { let should_export_executable_symbols = @@ -1116,9 +1132,10 @@ impl<'a> Linker for MsvcLinker<'a> { // straight to exports. writeln!(f, "LIBRARY")?; writeln!(f, "EXPORTS")?; - for symbol in symbols { + for (symbol, kind) in symbols { + let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" }; debug!(" _{symbol}"); - writeln!(f, " {symbol}")?; + writeln!(f, " {symbol}{kind_marker}")?; } }; if let Err(error) = res { @@ -1259,14 +1276,19 @@ impl<'a> Linker for EmLinker<'a> { self.cc_arg("-nodefaultlibs"); } - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + _tmpdir: &Path, + _crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { debug!("EXPORTED SYMBOLS:"); self.cc_arg("-s"); let mut arg = OsString::from("EXPORTED_FUNCTIONS="); let encoded = serde_json::to_string( - &symbols.iter().map(|sym| "_".to_owned() + sym).collect::>(), + &symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::>(), ) .unwrap(); debug!("{encoded}"); @@ -1428,8 +1450,13 @@ impl<'a> Linker for WasmLd<'a> { fn no_default_libraries(&mut self) {} - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { - for sym in symbols { + fn export_symbols( + &mut self, + _tmpdir: &Path, + _crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { + for (sym, _) in symbols { self.link_args(&["--export", sym]); } @@ -1563,7 +1590,7 @@ impl<'a> Linker for L4Bender<'a> { self.cc_arg("-nostdlib"); } - fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { + fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) { // ToDo, not implemented, copy from GCC self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented); } @@ -1720,12 +1747,17 @@ impl<'a> Linker for AixLinker<'a> { fn no_default_libraries(&mut self) {} - fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + tmpdir: &Path, + _crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { let path = tmpdir.join("list.exp"); let res: io::Result<()> = try { let mut f = File::create_buffered(&path)?; // FIXME: use llvm-nm to generate export list. - for symbol in symbols { + for (symbol, _) in symbols { debug!(" _{symbol}"); writeln!(f, " {symbol}")?; } @@ -1769,9 +1801,12 @@ fn for_each_exported_symbols_include_dep<'tcx>( } } -pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { +pub(crate) fn exported_symbols( + tcx: TyCtxt<'_>, + crate_type: CrateType, +) -> Vec<(String, SymbolExportKind)> { if let Some(ref exports) = tcx.sess.target.override_export_symbols { - return exports.iter().map(ToString::to_string).collect(); + return exports.iter().map(|name| (name.to_string(), SymbolExportKind::Text)).collect(); } if let CrateType::ProcMacro = crate_type { @@ -1781,7 +1816,10 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec, crate_type: CrateType) -> Vec { +fn exported_symbols_for_non_proc_macro( + tcx: TyCtxt<'_>, + crate_type: CrateType, +) -> Vec<(String, SymbolExportKind)> { let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { @@ -1789,17 +1827,18 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) - // from any cdylib. The latter doesn't work anyway as we use hidden visibility for // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning. if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) { - symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate( - tcx, symbol, cnum, + symbols.push(( + symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum), + info.kind, )); - symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum); + symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, info, cnum); } }); symbols } -fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec { +fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> { // `exported_symbols` will be empty when !should_codegen. if !tcx.sess.opts.output_types.should_codegen() { return Vec::new(); @@ -1809,7 +1848,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec { let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); - vec![proc_macro_decls_name, metadata_symbol_name] + vec![ + (proc_macro_decls_name, SymbolExportKind::Text), + (metadata_symbol_name, SymbolExportKind::Text), + ] } pub(crate) fn linked_symbols( @@ -1831,7 +1873,9 @@ pub(crate) fn linked_symbols( || info.used { symbols.push(( - symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum), + symbol_export::linking_symbol_name_for_instance_in_crate( + tcx, symbol, info.kind, cnum, + ), info.kind, )); } @@ -1906,7 +1950,13 @@ impl<'a> Linker for PtxLinker<'a> { fn ehcont_guard(&mut self) {} - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {} + fn export_symbols( + &mut self, + _tmpdir: &Path, + _crate_type: CrateType, + _symbols: &[(String, SymbolExportKind)], + ) { + } fn subsystem(&mut self, _subsystem: &str) {} @@ -1975,10 +2025,15 @@ impl<'a> Linker for LlbcLinker<'a> { fn ehcont_guard(&mut self) {} - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + _tmpdir: &Path, + _crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { match _crate_type { CrateType::Cdylib => { - for sym in symbols { + for (sym, _) in symbols { self.link_args(&["--export-symbol", sym]); } } @@ -2052,11 +2107,16 @@ impl<'a> Linker for BpfLinker<'a> { fn ehcont_guard(&mut self) {} - fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { + fn export_symbols( + &mut self, + tmpdir: &Path, + _crate_type: CrateType, + symbols: &[(String, SymbolExportKind)], + ) { let path = tmpdir.join("symbols"); let res: io::Result<()> = try { let mut f = File::create_buffered(&path)?; - for sym in symbols { + for (sym, _) in symbols { writeln!(f, "{sym}")?; } }; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 5f0a0cf922af..06ba5b4f6a75 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -692,6 +692,7 @@ fn calling_convention_for_symbol<'tcx>( pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, + export_kind: SymbolExportKind, instantiating_crate: CrateNum, ) -> String { let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate); @@ -712,8 +713,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( let prefix = match &target.arch[..] { "x86" => Some('_'), "x86_64" => None, - "arm64ec" => Some('#'), - // Only x86/64 use symbol decorations. + // Only functions are decorated for arm64ec. + "arm64ec" if export_kind == SymbolExportKind::Text => Some('#'), + // Only x86/64 and arm64ec use symbol decorations. _ => return undecorated, }; @@ -753,9 +755,10 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>( /// Add it to the symbols list for all kernel functions, so that it is exported in the linked /// object. pub(crate) fn extend_exported_symbols<'tcx>( - symbols: &mut Vec, + symbols: &mut Vec<(String, SymbolExportKind)>, tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, + info: SymbolExportInfo, instantiating_crate: CrateNum, ) { let (conv, _) = calling_convention_for_symbol(tcx, symbol); @@ -767,7 +770,7 @@ pub(crate) fn extend_exported_symbols<'tcx>( let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate); // Add the symbol for the kernel descriptor (with .kd suffix) - symbols.push(format!("{undecorated}.kd")); + symbols.push((format!("{undecorated}.kd"), info.kind)); } fn maybe_emutls_symbol_name<'tcx>( diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 775ab9071e74..93cbd4cbb7cc 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -12,9 +12,9 @@ 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::{IntoDynSyncSend, par_map}; use rustc_data_structures::unord::UnordMap; -use rustc_hir::ItemId; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; +use rustc_hir::{ItemId, Target}; use rustc_metadata::EncodedMetadata; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType}; @@ -1038,21 +1038,35 @@ impl CrateInfo { // by the compiler, but that's ok because all this stuff is unstable anyway. let target = &tcx.sess.target; if !are_upstream_rust_objects_already_included(tcx.sess) { - let missing_weak_lang_items: FxIndexSet = info + let add_prefix = match (target.is_like_windows, target.arch.as_ref()) { + (true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"), + (true, "arm64ec") => { + // Only functions are decorated for arm64ec. + |name: String, export_kind: SymbolExportKind| match export_kind { + SymbolExportKind::Text => format!("#{name}"), + _ => name, + } + } + _ => |name: String, _: SymbolExportKind| name, + }; + let missing_weak_lang_items: FxIndexSet<(Symbol, SymbolExportKind)> = info .used_crates .iter() .flat_map(|&cnum| tcx.missing_lang_items(cnum)) .filter(|l| l.is_weak()) .filter_map(|&l| { let name = l.link_name()?; - lang_items::required(tcx, l).then_some(name) + let export_kind = match l.target() { + Target::Fn => SymbolExportKind::Text, + Target::Static => SymbolExportKind::Data, + _ => bug!( + "Don't know what the export kind is for lang item of kind {:?}", + l.target() + ), + }; + lang_items::required(tcx, l).then_some((name, export_kind)) }) .collect(); - let prefix = match (target.is_like_windows, target.arch.as_ref()) { - (true, "x86") => "_", - (true, "arm64ec") => "#", - _ => "", - }; // This loop only adds new items to values of the hash map, so the order in which we // iterate over the values is not important. @@ -1065,10 +1079,13 @@ impl CrateInfo { .for_each(|(_, linked_symbols)| { let mut symbols = missing_weak_lang_items .iter() - .map(|item| { + .map(|(item, export_kind)| { ( - format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())), - SymbolExportKind::Text, + add_prefix( + mangle_internal_symbol(tcx, item.as_str()), + *export_kind, + ), + *export_kind, ) }) .collect::>(); @@ -1083,12 +1100,12 @@ impl CrateInfo { // errors. linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| { ( - format!( - "{prefix}{}", + add_prefix( mangle_internal_symbol( tcx, - global_fn_name(method.name).as_str() - ) + global_fn_name(method.name).as_str(), + ), + SymbolExportKind::Text, ), SymbolExportKind::Text, ) diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index bfec208c4aed..4f9757f198b8 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -219,7 +219,7 @@ pub struct CrateInfo { pub target_cpu: String, pub target_features: Vec, pub crate_types: Vec, - pub exported_symbols: UnordMap>, + pub exported_symbols: UnordMap>, pub linked_symbols: FxIndexMap>, pub local_crate_name: Symbol, pub compiler_builtins: Option, diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 1d67d0fe3bbf..64a1f2aff15c 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -22,7 +22,7 @@ impl SymbolExportLevel { } /// Kind of exported symbols. -#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)] +#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)] pub enum SymbolExportKind { Text, Data, diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs index 486d7158723f..bd59678d2366 100644 --- a/compiler/rustc_target/src/spec/base/msvc.rs +++ b/compiler/rustc_target/src/spec/base/msvc.rs @@ -5,7 +5,19 @@ use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo pub(crate) fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly // clog any log files. - let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]); + let pre_link_args = TargetOptions::link_args( + LinkerFlavor::Msvc(Lld::No), + &[ + "/NOLOGO", + // "Symbol is marked as dllimport, but defined in an object file" + // Harmless warning that flags a potential performance improvement: marking a symbol as + // dllimport indirects usage via the `__imp_` symbol, which isn't required if the symbol + // is in the current binary. This is tripped by __rust_no_alloc_shim_is_unstable as it + // is generated by the compiler, but marked as a foreign item (hence the dllimport) in + // the standard library. + "/IGNORE:4286", + ], + ); TargetOptions { linker_flavor: LinkerFlavor::Msvc(Lld::No), diff --git a/tests/run-make/arm64ec-import-export-static/export.rs b/tests/run-make/arm64ec-import-export-static/export.rs new file mode 100644 index 000000000000..98b3a66d80c0 --- /dev/null +++ b/tests/run-make/arm64ec-import-export-static/export.rs @@ -0,0 +1,23 @@ +#![crate_type = "dylib"] +#![allow(internal_features)] +#![feature(no_core, lang_items)] +#![no_core] +#![no_std] + +// This is needed because of #![no_core]: +#[lang = "sized"] +trait Sized {} +#[lang = "sync"] +trait Sync {} +impl Sync for i32 {} +#[lang = "copy"] +pub trait Copy {} +impl Copy for i32 {} +#[lang = "drop_in_place"] +pub unsafe fn drop_in_place(_: *mut T) {} +#[no_mangle] +extern "system" fn _DllMainCRTStartup(_: *const u8, _: u32, _: *const u8) -> u32 { + 1 +} + +pub static VALUE: i32 = 42; diff --git a/tests/run-make/arm64ec-import-export-static/import.rs b/tests/run-make/arm64ec-import-export-static/import.rs new file mode 100644 index 000000000000..9d52db251250 --- /dev/null +++ b/tests/run-make/arm64ec-import-export-static/import.rs @@ -0,0 +1,12 @@ +#![crate_type = "cdylib"] +#![allow(internal_features)] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate export; + +#[no_mangle] +pub extern "C" fn func() -> i32 { + export::VALUE +} diff --git a/tests/run-make/arm64ec-import-export-static/rmake.rs b/tests/run-make/arm64ec-import-export-static/rmake.rs new file mode 100644 index 000000000000..7fa31144810d --- /dev/null +++ b/tests/run-make/arm64ec-import-export-static/rmake.rs @@ -0,0 +1,15 @@ +// Test that a static can be exported from one crate and imported into another. +// +// This was broken for Arm64EC as only functions, not variables, should be +// decorated with `#`. +// See https://github.com/rust-lang/rust/issues/138541 + +//@ needs-llvm-components: aarch64 +//@ only-windows + +use run_make_support::rustc; + +fn main() { + rustc().input("export.rs").target("aarch64-pc-windows-msvc").panic("abort").run(); + rustc().input("import.rs").target("aarch64-pc-windows-msvc").panic("abort").run(); +} diff --git a/tests/run-make/sanitizer-dylib-link/program.rs b/tests/run-make/sanitizer-dylib-link/program.rs index 1026c7f89ba9..dbf885d343fe 100644 --- a/tests/run-make/sanitizer-dylib-link/program.rs +++ b/tests/run-make/sanitizer-dylib-link/program.rs @@ -1,4 +1,4 @@ -#[cfg_attr(windows, link(name = "library.dll.lib", modifiers = "+verbatim"))] +#[cfg_attr(windows, link(name = "library", kind = "raw-dylib"))] #[cfg_attr(not(windows), link(name = "library"))] extern "C" { fn overflow(); From 3286d4aad789a48bfaef5a682d6dcf2642012216 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 7 May 2025 10:46:36 -0700 Subject: [PATCH 228/262] [win][arm64] Disable various DebugInfo tests that don't work on Arm64 Windows --- src/tools/compiletest/src/directive-list.rs | 1 + tests/debuginfo/step-into-match.rs | 4 ++++ tests/debuginfo/type-names.rs | 2 ++ tests/ui/runtime/backtrace-debuginfo.rs | 4 ++++ 4 files changed, 11 insertions(+) diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 1449e9af19aa..5757e422ae21 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -35,6 +35,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-32bit", "ignore-64bit", "ignore-aarch64", + "ignore-aarch64-pc-windows-msvc", "ignore-aarch64-unknown-linux-gnu", "ignore-aix", "ignore-android", diff --git a/tests/debuginfo/step-into-match.rs b/tests/debuginfo/step-into-match.rs index 577e553c1198..d4b7ea201195 100644 --- a/tests/debuginfo/step-into-match.rs +++ b/tests/debuginfo/step-into-match.rs @@ -1,6 +1,10 @@ //@ compile-flags: -g //@ ignore-android: FIXME(#10381) +// On Arm64 Windows, stepping at the end of a function on goes to the callsite, not the instruction +// after it. +//@ ignore-aarch64-pc-windows-msvc: Stepping out of functions behaves differently. + // === GDB TESTS ============================================================== // gdb-command: r diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs index 4df6daf7b6ef..3c7eab7e8d71 100644 --- a/tests/debuginfo/type-names.rs +++ b/tests/debuginfo/type-names.rs @@ -1,5 +1,7 @@ //@ ignore-lldb +//@ ignore-aarch64-pc-windows-msvc: Arm64 Windows cdb doesn't support JavaScript extensions. + // GDB changed the way that it formatted Foreign types //@ min-gdb-version: 9.2 diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index afc96d6bb5f5..37fce2788b7f 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -42,9 +42,13 @@ macro_rules! dump_and_die { // there, even on i686-pc-windows-msvc. We do the best we can in // rust-lang/rust to test it as well, but sometimes we just gotta keep // landing PRs. + // + // aarch64-msvc is broken as its backtraces are truncated. + // See https://github.com/rust-lang/rust/issues/140489 if cfg!(any(target_os = "android", all(target_os = "linux", target_arch = "arm"), all(target_env = "msvc", target_arch = "x86"), + all(target_env = "msvc", target_arch = "aarch64"), target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")) { From 742aaf9b697a43c0da8c55fd234f8088f1cfe79c Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 7 May 2025 10:52:18 -0700 Subject: [PATCH 229/262] [arm64] Pointer auth test should link with C static library statically --- tests/run-make/pointer-auth-link-with-c/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/pointer-auth-link-with-c/test.rs b/tests/run-make/pointer-auth-link-with-c/test.rs index 1a3be80e898b..795c6a45f8e6 100644 --- a/tests/run-make/pointer-auth-link-with-c/test.rs +++ b/tests/run-make/pointer-auth-link-with-c/test.rs @@ -1,4 +1,4 @@ -#[link(name = "test")] +#[link(name = "test", kind = "static")] extern "C" { fn foo() -> i32; } From fc0ef54fd9fab0c31f89c53ae83f7afdb767829d Mon Sep 17 00:00:00 2001 From: lcnr Date: Sun, 4 May 2025 17:35:39 +0000 Subject: [PATCH 230/262] opaque_type_storage to InferCtxtLike --- compiler/rustc_infer/src/infer/context.rs | 39 +++++++++++++++ .../rustc_next_trait_solver/src/delegate.rs | 22 --------- .../src/solve/delegate.rs | 47 ------------------- compiler/rustc_type_ir/src/infer_ctxt.rs | 22 +++++++++ 4 files changed, 61 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 22d7ce79bb46..ad9e176c5924 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -213,4 +213,43 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) { self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span)); } + + fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect() + } + fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.inner + .borrow_mut() + .opaque_types() + .iter_duplicate_entries() + .map(|(k, h)| (k, h.ty)) + .collect() + } + + fn register_hidden_type_in_storage( + &self, + opaque_type_key: ty::OpaqueTypeKey<'tcx>, + hidden_ty: Ty<'tcx>, + span: Span, + ) -> Option> { + self.register_hidden_type_in_storage( + opaque_type_key, + ty::OpaqueHiddenType { span, ty: hidden_ty }, + ) + } + fn add_duplicate_opaque_type( + &self, + opaque_type_key: ty::OpaqueTypeKey<'tcx>, + hidden_ty: Ty<'tcx>, + span: Span, + ) { + self.inner + .borrow_mut() + .opaque_types() + .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }) + } + + fn reset_opaque_types(&self) { + let _ = self.take_opaque_types(); + } } diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 9e8fbd66b708..90a7c2e9f787 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -39,13 +39,6 @@ pub trait SolverDelegate: Deref + Sized { term: ::Term, ) -> Option::Predicate>>>; - fn clone_opaque_types_lookup_table( - &self, - ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; - fn clone_duplicate_opaque_types( - &self, - ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; - fn make_deduplicated_outlives_constraints( &self, ) -> Vec::GenericArg>>; @@ -64,20 +57,6 @@ pub trait SolverDelegate: Deref + Sized { span: ::Span, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> ::GenericArg; - - fn register_hidden_type_in_storage( - &self, - opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: ::Ty, - span: ::Span, - ) -> Option<::Ty>; - fn add_duplicate_opaque_type( - &self, - opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: ::Ty, - span: ::Span, - ); - fn add_item_bounds_for_hidden_type( &self, def_id: ::DefId, @@ -86,7 +65,6 @@ pub trait SolverDelegate: Deref + Sized { hidden_ty: ::Ty, goals: &mut Vec::Predicate>>, ); - fn reset_opaque_types(&self); fn fetch_eligible_assoc_item( &self, diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 87b8db59a78e..3601c2cba9b5 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -104,25 +104,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< .map(|obligations| obligations.into_iter().map(|obligation| obligation.as_goal()).collect()) } - fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { - self.0 - .inner - .borrow_mut() - .opaque_types() - .iter_lookup_table() - .map(|(k, h)| (k, h.ty)) - .collect() - } - fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { - self.0 - .inner - .borrow_mut() - .opaque_types() - .iter_duplicate_entries() - .map(|(k, h)| (k, h.ty)) - .collect() - } - fn make_deduplicated_outlives_constraints( &self, ) -> Vec>> { @@ -168,30 +149,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< self.0.instantiate_canonical_var(span, cv_info, universe_map) } - fn register_hidden_type_in_storage( - &self, - opaque_type_key: ty::OpaqueTypeKey<'tcx>, - hidden_ty: Ty<'tcx>, - span: Span, - ) -> Option> { - self.0.register_hidden_type_in_storage( - opaque_type_key, - ty::OpaqueHiddenType { span, ty: hidden_ty }, - ) - } - fn add_duplicate_opaque_type( - &self, - opaque_type_key: ty::OpaqueTypeKey<'tcx>, - hidden_ty: Ty<'tcx>, - span: Span, - ) { - self.0 - .inner - .borrow_mut() - .opaque_types() - .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }) - } - fn add_item_bounds_for_hidden_type( &self, def_id: DefId, @@ -203,10 +160,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals); } - fn reset_opaque_types(&self) { - let _ = self.take_opaque_types(); - } - fn fetch_eligible_assoc_item( &self, goal_trait_ref: ty::TraitRef<'tcx>, diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 8fa56c359996..4e6f7987810b 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -245,4 +245,26 @@ pub trait InferCtxtLike: Sized { r: ::Region, span: ::Span, ); + + fn clone_opaque_types_lookup_table( + &self, + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; + fn clone_duplicate_opaque_types( + &self, + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; + + fn register_hidden_type_in_storage( + &self, + opaque_type_key: ty::OpaqueTypeKey, + hidden_ty: ::Ty, + span: ::Span, + ) -> Option<::Ty>; + fn add_duplicate_opaque_type( + &self, + opaque_type_key: ty::OpaqueTypeKey, + hidden_ty: ::Ty, + span: ::Span, + ); + + fn reset_opaque_types(&self); } From e7979eab891c4dd603f73d31b0d50e58a1c3f29c Mon Sep 17 00:00:00 2001 From: lcnr Date: Sun, 4 May 2025 17:19:54 +0000 Subject: [PATCH 231/262] detect additional uses of opaques after writeback --- compiler/rustc_hir_typeck/src/lib.rs | 5 +- compiler/rustc_hir_typeck/src/opaque_types.rs | 26 ++++++++++ .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 15 ++++-- compiler/rustc_hir_typeck/src/writeback.rs | 9 ++-- compiler/rustc_infer/src/infer/context.rs | 20 +++++++- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 +- .../src/infer/opaque_types/table.rs | 28 ++++++++++ .../src/solve/eval_ctxt/canonical.rs | 8 +-- .../src/solve/eval_ctxt/mod.rs | 51 +++++++++---------- .../src/solve/eval_ctxt/probe.rs | 39 +++++++------- compiler/rustc_type_ir/src/infer_ctxt.rs | 8 +++ 12 files changed, 143 insertions(+), 70 deletions(-) create mode 100644 compiler/rustc_hir_typeck/src/opaque_types.rs diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 78233a34c461..60187abd5589 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -32,6 +32,7 @@ mod gather_locals; mod intrinsicck; mod method; mod op; +mod opaque_types; mod pat; mod place_op; mod rvalue_scopes; @@ -245,9 +246,7 @@ fn typeck_with_inspect<'tcx>( let typeck_results = fcx.resolve_type_vars_in_body(body); - // We clone the defined opaque types during writeback in the new solver - // because we have to use them during normalization. - let _ = fcx.infcx.take_opaque_types(); + fcx.detect_opaque_types_added_during_writeback(); // Consistency check our TypeckResults instance can hold all ItemLocalIds // it will need to hold. diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs new file mode 100644 index 000000000000..e0224f8c6e1b --- /dev/null +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -0,0 +1,26 @@ +use super::FnCtxt; +impl<'tcx> FnCtxt<'_, 'tcx> { + /// We may in theory add further uses of an opaque after cloning the opaque + /// types storage during writeback when computing the defining uses. + /// + /// Silently ignoring them is dangerous and could result in ICE or even in + /// unsoundness, so we make sure we catch such cases here. There's currently + /// no known code where this actually happens, even with the new solver which + /// does normalize types in writeback after cloning the opaque type storage. + /// + /// FIXME(@lcnr): I believe this should be possible in theory and would like + /// an actual test here. After playing around with this for an hour, I wasn't + /// able to do anything which didn't already try to normalize the opaque before + /// then, either allowing compilation to succeed or causing an ambiguity error. + pub(super) fn detect_opaque_types_added_during_writeback(&self) { + let num_entries = self.checked_opaque_types_storage_entries.take().unwrap(); + for (key, hidden_type) in + self.inner.borrow_mut().opaque_types().opaque_types_added_since(num_entries) + { + let opaque_type_string = self.tcx.def_path_str(key.def_id); + let msg = format!("unexpected cyclic definition of `{opaque_type_string}`"); + self.dcx().span_delayed_bug(hidden_type.span, msg); + } + let _ = self.take_opaque_types(); + } +} diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 56859eef45f7..26be5fc6d190 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -1,10 +1,10 @@ -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::ops::Deref; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, HirId, HirIdMap, LangItem}; -use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, InferOk, OpaqueTypeStorageEntries, TyCtxtInferExt}; use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_span::Span; @@ -37,6 +37,11 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) fulfillment_cx: RefCell>>>, + // Used to detect opaque types uses added after we've already checked them. + // + // See [FnCtxt::detect_opaque_types_added_during_writeback] for more details. + pub(super) checked_opaque_types_storage_entries: Cell>, + /// Some additional `Sized` obligations badly affect type inference. /// These obligations are added in a later stage of typeck. /// Removing these may also cause additional complications, see #101066. @@ -85,12 +90,14 @@ impl<'tcx> TypeckRootCtxt<'tcx> { let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::typeck_for_body(tcx, def_id)); let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner)); + let fulfillment_cx = RefCell::new(>::new(&infcx)); TypeckRootCtxt { - typeck_results, - fulfillment_cx: RefCell::new(>::new(&infcx)), infcx, + typeck_results, locals: RefCell::new(Default::default()), + fulfillment_cx, + checked_opaque_types_storage_entries: Cell::new(None), deferred_sized_obligations: RefCell::new(Vec::new()), deferred_call_resolutions: RefCell::new(Default::default()), deferred_cast_checks: RefCell::new(Vec::new()), diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 8e7ce83044cd..9be041f75d76 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -535,13 +535,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let tcx = self.tcx(); // We clone the opaques instead of stealing them here as they are still used for // normalization in the next generation trait solver. - // - // FIXME(-Znext-solver): Opaque types defined after this would simply get dropped - // at the end of typeck. While this seems unlikely to happen in practice this - // should still get fixed. Either by preventing writeback from defining new opaque - // types or by using this function at the end of writeback and running it as a - // fixpoint. let opaque_types = self.fcx.infcx.clone_opaque_types(); + let num_entries = self.fcx.inner.borrow_mut().opaque_types().num_entries(); + let prev = self.fcx.checked_opaque_types_storage_entries.replace(Some(num_entries)); + debug_assert_eq!(prev, None); for (opaque_type_key, hidden_type) in opaque_types { let hidden_type = self.resolve(hidden_type, &hidden_type.span); let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span); diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index ad9e176c5924..359b9da11ced 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -6,7 +6,10 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; -use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin}; +use super::{ + BoundRegionConversionTime, InferCtxt, OpaqueTypeStorageEntries, RegionVariableOrigin, + SubregionOrigin, +}; impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { type Interner = TyCtxt<'tcx>; @@ -214,6 +217,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span)); } + type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries; + fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries { + self.inner.borrow_mut().opaque_types().num_entries() + } fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect() } @@ -225,6 +232,17 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { .map(|(k, h)| (k, h.ty)) .collect() } + fn clone_opaque_types_added_since( + &self, + prev_entries: OpaqueTypeStorageEntries, + ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.inner + .borrow_mut() + .opaque_types() + .opaque_types_added_since(prev_entries) + .map(|(k, h)| (k, h.ty)) + .collect() + } fn register_hidden_type_in_storage( &self, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 070d285b5a63..b408d76010d7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -9,7 +9,7 @@ use free_regions::RegionRelations; pub use freshen::TypeFreshener; use lexical_region_resolve::LexicalRegionResolutions; pub use lexical_region_resolve::RegionResolutionError; -use opaque_types::OpaqueTypeStorage; +pub use opaque_types::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable}; use region_constraints::{ GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound, }; diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index df7144c31da5..220d5e9bda2d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -18,7 +18,7 @@ use crate::traits::{self, Obligation, PredicateObligations}; mod table; -pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable}; +pub use table::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable}; impl<'tcx> InferCtxt<'tcx> { /// This is a backwards compatibility hack to prevent breaking changes from diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index 3c5bf9d722b9..46752840e1ba 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -14,6 +14,16 @@ pub struct OpaqueTypeStorage<'tcx> { duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, } +/// The number of entries in the opaque type storage at a given point. +/// +/// Used to check that we haven't added any new opaque types after checking +/// the opaque types currently in the storage. +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +pub struct OpaqueTypeStorageEntries { + opaque_types: usize, + duplicate_entries: usize, +} + impl<'tcx> OpaqueTypeStorage<'tcx> { #[instrument(level = "debug")] pub(crate) fn remove( @@ -49,6 +59,24 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries)) } + pub fn num_entries(&self) -> OpaqueTypeStorageEntries { + OpaqueTypeStorageEntries { + opaque_types: self.opaque_types.len(), + duplicate_entries: self.duplicate_entries.len(), + } + } + + pub fn opaque_types_added_since( + &self, + prev_entries: OpaqueTypeStorageEntries, + ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + self.opaque_types + .iter() + .skip(prev_entries.opaque_types) + .map(|(k, v)| (*k, *v)) + .chain(self.duplicate_entries.iter().skip(prev_entries.duplicate_entries).copied()) + } + /// Only returns the opaque types from the lookup table. These are used /// when normalizing opaque types and have a unique key. /// diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 65b10e4f23f0..f87b1367d6a6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -250,13 +250,7 @@ where // to the `var_values`. let opaque_types = self .delegate - .clone_opaque_types_lookup_table() - .into_iter() - .filter(|(a, _)| { - self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a) - }) - .chain(self.delegate.clone_duplicate_opaque_types()) - .collect(); + .clone_opaque_types_added_since(self.initial_opaque_types_storage_num_entries); ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c13e73080550..9d7f13692bbc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -23,8 +23,7 @@ use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::search_graph::SearchGraph; use crate::solve::{ CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource, - HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput, - QueryResult, + HasChanged, NestedNormalizationGoals, NoSolution, QueryInput, QueryResult, }; pub(super) mod canonical; @@ -99,8 +98,6 @@ where current_goal_kind: CurrentGoalKind, pub(super) var_values: CanonicalVarValues, - predefined_opaques_in_body: I::PredefinedOpaques, - /// The highest universe index nameable by the caller. /// /// When we enter a new binder inside of the query we create new universes @@ -111,6 +108,10 @@ where /// if we have a coinductive cycle and because that's the only way we can return /// new placeholders to the caller. pub(super) max_input_universe: ty::UniverseIndex, + /// The opaque types from the canonical input. We only need to return opaque types + /// which have been added to the storage while evaluating this goal. + pub(super) initial_opaque_types_storage_num_entries: + ::OpaqueTypeStorageEntries, pub(super) search_graph: &'a mut SearchGraph, @@ -305,10 +306,8 @@ where // Only relevant when canonicalizing the response, // which we don't do within this evaluation context. - predefined_opaques_in_body: delegate - .cx() - .mk_predefined_opaques_in_body(PredefinedOpaquesData::default()), max_input_universe: ty::UniverseIndex::ROOT, + initial_opaque_types_storage_num_entries: Default::default(), variables: Default::default(), var_values: CanonicalVarValues::dummy(), current_goal_kind: CurrentGoalKind::Misc, @@ -342,25 +341,10 @@ where canonical_goal_evaluation: &mut ProofTreeBuilder, f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal) -> R, ) -> R { - let (ref delegate, input, var_values) = - SolverDelegate::build_with_canonical(cx, &canonical_input); - - let mut ecx = EvalCtxt { - delegate, - variables: canonical_input.canonical.variables, - var_values, - current_goal_kind: CurrentGoalKind::from_query_input(cx, input), - predefined_opaques_in_body: input.predefined_opaques_in_body, - max_input_universe: canonical_input.canonical.max_universe, - search_graph, - nested_goals: Default::default(), - origin_span: I::Span::dummy(), - tainted: Ok(()), - inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values), - }; + let (ref delegate, input, var_values) = D::build_with_canonical(cx, &canonical_input); for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { - let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span); + let prev = delegate.register_hidden_type_in_storage(key, ty, I::Span::dummy()); // It may be possible that two entries in the opaque type storage end up // with the same key after resolving contained inference variables. // @@ -373,13 +357,24 @@ where // the canonical input. This is more annoying to implement and may cause a // perf regression, so we do it inside of the query for now. if let Some(prev) = prev { - debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_type_storage`"); + debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_types_storage`"); } } - if !ecx.nested_goals.is_empty() { - panic!("prepopulating opaque types shouldn't add goals: {:?}", ecx.nested_goals); - } + let initial_opaque_types_storage_num_entries = delegate.opaque_types_storage_num_entries(); + let mut ecx = EvalCtxt { + delegate, + variables: canonical_input.canonical.variables, + var_values, + current_goal_kind: CurrentGoalKind::from_query_input(cx, input), + max_input_universe: canonical_input.canonical.max_universe, + initial_opaque_types_storage_num_entries, + search_graph, + nested_goals: Default::default(), + origin_span: I::Span::dummy(), + tainted: Ok(()), + inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values), + }; let result = f(&mut ecx, input.goal); ecx.inspect.probe_final_state(ecx.delegate, ecx.max_input_universe); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs index 0a9e7fafaea6..ed0cedc40774 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs @@ -26,32 +26,33 @@ where I: Interner, { pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T) -> T { - let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self; + let ProbeCtxt { ecx: outer, probe_kind, _result } = self; - let delegate = outer_ecx.delegate; - let max_input_universe = outer_ecx.max_input_universe; - let mut nested_ecx = EvalCtxt { + let delegate = outer.delegate; + let max_input_universe = outer.max_input_universe; + let mut nested = EvalCtxt { delegate, - variables: outer_ecx.variables, - var_values: outer_ecx.var_values, - current_goal_kind: outer_ecx.current_goal_kind, - predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body, + variables: outer.variables, + var_values: outer.var_values, + current_goal_kind: outer.current_goal_kind, max_input_universe, - search_graph: outer_ecx.search_graph, - nested_goals: outer_ecx.nested_goals.clone(), - origin_span: outer_ecx.origin_span, - tainted: outer_ecx.tainted, - inspect: outer_ecx.inspect.take_and_enter_probe(), + initial_opaque_types_storage_num_entries: outer + .initial_opaque_types_storage_num_entries, + search_graph: outer.search_graph, + nested_goals: outer.nested_goals.clone(), + origin_span: outer.origin_span, + tainted: outer.tainted, + inspect: outer.inspect.take_and_enter_probe(), }; - let r = nested_ecx.delegate.probe(|| { - let r = f(&mut nested_ecx); - nested_ecx.inspect.probe_final_state(delegate, max_input_universe); + let r = nested.delegate.probe(|| { + let r = f(&mut nested); + nested.inspect.probe_final_state(delegate, max_input_universe); r }); - if !nested_ecx.inspect.is_noop() { + if !nested.inspect.is_noop() { let probe_kind = probe_kind(&r); - nested_ecx.inspect.probe_kind(probe_kind); - outer_ecx.inspect = nested_ecx.inspect.finish_probe(); + nested.inspect.probe_kind(probe_kind); + outer.inspect = nested.inspect.finish_probe(); } r } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 4e6f7987810b..1d59be7a20ae 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; @@ -246,12 +248,18 @@ pub trait InferCtxtLike: Sized { span: ::Span, ); + type OpaqueTypeStorageEntries: Debug + Copy + Default; + fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries; fn clone_opaque_types_lookup_table( &self, ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn clone_duplicate_opaque_types( &self, ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; + fn clone_opaque_types_added_since( + &self, + prev_entries: Self::OpaqueTypeStorageEntries, + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn register_hidden_type_in_storage( &self, From 0cacc05531a4cf5229213e65eae2763ee4cf293e Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 7 May 2025 11:12:11 -0700 Subject: [PATCH 232/262] [win][arm64] Disable FS tests that require symlinks --- library/std/src/fs/tests.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 46b0d832fec4..c81a5ff4d96e 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -730,6 +730,10 @@ fn recursive_mkdir_empty() { } #[test] +#[cfg_attr( + all(windows, target_arch = "aarch64"), + ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94" +)] fn recursive_rmdir() { let tmpdir = tmpdir(); let d1 = tmpdir.join("d1"); @@ -749,6 +753,10 @@ fn recursive_rmdir() { } #[test] +#[cfg_attr( + all(windows, target_arch = "aarch64"), + ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94" +)] fn recursive_rmdir_of_symlink() { // test we do not recursively delete a symlink but only dirs. let tmpdir = tmpdir(); @@ -1533,6 +1541,10 @@ fn file_open_not_found() { } #[test] +#[cfg_attr( + all(windows, target_arch = "aarch64"), + ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94" +)] fn create_dir_all_with_junctions() { let tmpdir = tmpdir(); let target = tmpdir.join("target"); @@ -2011,6 +2023,10 @@ fn test_rename_symlink() { #[test] #[cfg(windows)] +#[cfg_attr( + all(windows, target_arch = "aarch64"), + ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94" +)] fn test_rename_junction() { let tmpdir = tmpdir(); let original = tmpdir.join("original"); From f03d246db98e0b67f38b015bcc86a23d9c1e9adf Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 1 May 2025 01:03:43 +0000 Subject: [PATCH 233/262] Better error message for late/early lifetime param mismatch --- .../src/check/compare_impl_item.rs | 237 +++++++++++++++++- .../regions-bound-missing-bound-in-impl.rs | 6 +- ...regions-bound-missing-bound-in-impl.stderr | 96 +++++-- tests/ui/error-codes/E0195.rs | 19 +- tests/ui/error-codes/E0195.stderr | 42 +++- ...g-where-clause-lifetimes-from-trait.stderr | 57 +++-- 6 files changed, 403 insertions(+), 54 deletions(-) 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 553d981aa38a..fb67f2fd2235 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -5,7 +5,7 @@ use std::iter; use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; -use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; +use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit}; @@ -14,10 +14,10 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, + TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast, }; use rustc_middle::{bug, span_bug}; -use rustc_span::Span; +use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -1141,6 +1141,10 @@ fn check_region_bounds_on_impl_item<'tcx>( return Ok(()); } + if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) { + return Err(guar); + } + let span = tcx .hir_get_generics(impl_m.def_id.expect_local()) .expect("expected impl item to have generics or else we can't compare them") @@ -1221,6 +1225,233 @@ fn check_region_bounds_on_impl_item<'tcx>( Err(reported) } +#[allow(unused)] +enum LateEarlyMismatch<'tcx> { + EarlyInImpl(DefId, DefId, ty::Region<'tcx>), + LateInImpl(DefId, DefId, ty::Region<'tcx>), +} + +fn check_region_late_boundedness<'tcx>( + tcx: TyCtxt<'tcx>, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, +) -> Option { + if !impl_m.is_fn() { + return None; + } + + let (infcx, param_env) = tcx + .infer_ctxt() + .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id)); + + let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id); + let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args); + let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig); + + let trait_m_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id); + let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args); + let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig); + + let ocx = ObligationCtxt::new(&infcx); + + // Equate the signatures so that we can infer whether a late-bound param was present where + // an early-bound param was expected, since we replace the late-bound lifetimes with + // `ReLateParam`, and early-bound lifetimes with infer vars, so the early-bound args will + // resolve to `ReLateParam` if there is a mismatch. + let Ok(()) = ocx.eq( + &ObligationCause::dummy(), + param_env, + ty::Binder::dummy(trait_m_sig), + ty::Binder::dummy(impl_m_sig), + ) else { + return None; + }; + + let errors = ocx.select_where_possible(); + if !errors.is_empty() { + return None; + } + + let mut mismatched = vec![]; + + let impl_generics = tcx.generics_of(impl_m.def_id); + for (id_arg, arg) in + std::iter::zip(ty::GenericArgs::identity_for_item(tcx, impl_m.def_id), impl_m_args) + { + if let ty::GenericArgKind::Lifetime(r) = arg.unpack() + && let ty::ReVar(vid) = r.kind() + && let r = infcx + .inner + .borrow_mut() + .unwrap_region_constraints() + .opportunistic_resolve_var(tcx, vid) + && let ty::ReLateParam(ty::LateParamRegion { + kind: ty::LateParamRegionKind::Named(trait_param_def_id, _), + .. + }) = r.kind() + && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind() + { + mismatched.push(LateEarlyMismatch::EarlyInImpl( + impl_generics.region_param(ebr, tcx).def_id, + trait_param_def_id, + id_arg.expect_region(), + )); + } + } + + let trait_generics = tcx.generics_of(trait_m.def_id); + for (id_arg, arg) in + std::iter::zip(ty::GenericArgs::identity_for_item(tcx, trait_m.def_id), trait_m_args) + { + if let ty::GenericArgKind::Lifetime(r) = arg.unpack() + && let ty::ReVar(vid) = r.kind() + && let r = infcx + .inner + .borrow_mut() + .unwrap_region_constraints() + .opportunistic_resolve_var(tcx, vid) + && let ty::ReLateParam(ty::LateParamRegion { + kind: ty::LateParamRegionKind::Named(impl_param_def_id, _), + .. + }) = r.kind() + && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind() + { + mismatched.push(LateEarlyMismatch::LateInImpl( + impl_param_def_id, + trait_generics.region_param(ebr, tcx).def_id, + id_arg.expect_region(), + )); + } + } + + if mismatched.is_empty() { + return None; + } + + let spans: Vec<_> = mismatched + .iter() + .map(|param| { + let (LateEarlyMismatch::EarlyInImpl(impl_param_def_id, ..) + | LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = param; + tcx.def_span(impl_param_def_id) + }) + .collect(); + + let mut diag = tcx + .dcx() + .struct_span_err(spans, "lifetime parameters do not match the trait definition") + .with_note("lifetime parameters differ in whether they are early- or late-bound") + .with_code(E0195); + for mismatch in mismatched { + match mismatch { + LateEarlyMismatch::EarlyInImpl( + impl_param_def_id, + trait_param_def_id, + early_bound_region, + ) => { + let mut multispan = MultiSpan::from_spans(vec![ + tcx.def_span(impl_param_def_id), + tcx.def_span(trait_param_def_id), + ]); + multispan + .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl..."); + multispan + .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait..."); + multispan.push_span_label( + tcx.def_span(impl_param_def_id), + format!("`{}` is early-bound", tcx.item_name(impl_param_def_id)), + ); + multispan.push_span_label( + tcx.def_span(trait_param_def_id), + format!("`{}` is late-bound", tcx.item_name(trait_param_def_id)), + ); + if let Some(span) = + find_region_in_predicates(tcx, impl_m.def_id, early_bound_region) + { + multispan.push_span_label( + span, + format!( + "this lifetime bound makes `{}` early-bound", + tcx.item_name(impl_param_def_id) + ), + ); + } + diag.span_note( + multispan, + format!( + "`{}` differs between the trait and impl", + tcx.item_name(impl_param_def_id) + ), + ); + } + LateEarlyMismatch::LateInImpl( + impl_param_def_id, + trait_param_def_id, + early_bound_region, + ) => { + let mut multispan = MultiSpan::from_spans(vec![ + tcx.def_span(impl_param_def_id), + tcx.def_span(trait_param_def_id), + ]); + multispan + .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl..."); + multispan + .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait..."); + multispan.push_span_label( + tcx.def_span(impl_param_def_id), + format!("`{}` is late-bound", tcx.item_name(impl_param_def_id)), + ); + multispan.push_span_label( + tcx.def_span(trait_param_def_id), + format!("`{}` is early-bound", tcx.item_name(trait_param_def_id)), + ); + if let Some(span) = + find_region_in_predicates(tcx, trait_m.def_id, early_bound_region) + { + multispan.push_span_label( + span, + format!( + "this lifetime bound makes `{}` early-bound", + tcx.item_name(trait_param_def_id) + ), + ); + } + diag.span_note( + multispan, + format!( + "`{}` differs between the trait and impl", + tcx.item_name(impl_param_def_id) + ), + ); + } + } + } + + Some(diag.emit()) +} + +fn find_region_in_predicates<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + early_bound_region: ty::Region<'tcx>, +) -> Option { + for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) { + if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() { + return Some(span); + } + } + + struct FindRegion<'tcx>(ty::Region<'tcx>); + impl<'tcx> TypeVisitor> for FindRegion<'tcx> { + type Result = ControlFlow<()>; + fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { + if r == self.0 { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + } + } + + None +} + #[instrument(level = "debug", skip(infcx))] fn extract_spans_for_error_reporting<'tcx>( infcx: &infer::InferCtxt<'tcx>, diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs index 141ad5bd2c48..7c0378e068be 100644 --- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs +++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs @@ -17,11 +17,11 @@ pub trait Foo<'a, 't> { impl<'a, 't> Foo<'a, 't> for &'a isize { fn no_bound<'b:'a>(self, b: Inv<'b>) { - //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match + //~^ ERROR lifetime parameters do not match the trait definition } fn has_bound<'b>(self, b: Inv<'b>) { - //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match + //~^ ERROR lifetime parameters do not match the trait definition } fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { @@ -40,7 +40,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize { } fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { - //~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait + //~^ ERROR lifetime parameters do not match the trait definition } fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) { diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 2afacd4cc952..207ca57af38b 100644 --- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -1,23 +1,48 @@ -error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:19:16 +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/regions-bound-missing-bound-in-impl.rs:19:17 | -LL | fn no_bound<'b>(self, b: Inv<'b>); - | ---- lifetimes in impl do not match this method in trait -... LL | fn no_bound<'b:'a>(self, b: Inv<'b>) { - | ^^^^^^^ lifetimes do not match method in trait - -error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:23:17 + | ^^ | + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'b` differs between the trait and impl + --> $DIR/regions-bound-missing-bound-in-impl.rs:10:17 + | +LL | pub trait Foo<'a, 't> { + | --------------------- in this trait... +LL | fn no_bound<'b>(self, b: Inv<'b>); + | ^^ `'b` is late-bound +... +LL | impl<'a, 't> Foo<'a, 't> for &'a isize { + | -------------------------------------- in this impl... +LL | fn no_bound<'b:'a>(self, b: Inv<'b>) { + | ^^ -- this lifetime bound makes `'b` early-bound + | | + | `'b` is early-bound + +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/regions-bound-missing-bound-in-impl.rs:23:18 + | +LL | fn has_bound<'b>(self, b: Inv<'b>) { + | ^^ + | + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'b` differs between the trait and impl + --> $DIR/regions-bound-missing-bound-in-impl.rs:11:18 + | +LL | pub trait Foo<'a, 't> { + | --------------------- in this trait... +LL | fn no_bound<'b>(self, b: Inv<'b>); LL | fn has_bound<'b:'a>(self, b: Inv<'b>); - | ------- - | | | - | | this bound might be missing in the impl - | lifetimes in impl do not match this method in trait + | ^^ -- this lifetime bound makes `'b` early-bound + | | + | `'b` is early-bound +... +LL | impl<'a, 't> Foo<'a, 't> for &'a isize { + | -------------------------------------- in this impl... ... LL | fn has_bound<'b>(self, b: Inv<'b>) { - | ^^^^ lifetimes do not match method in trait + | ^^ `'b` is late-bound error[E0308]: method not compatible with trait --> $DIR/regions-bound-missing-bound-in-impl.rs:27:5 @@ -57,18 +82,45 @@ note: ...does not necessarily outlive the lifetime `'c` as defined here LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^ -error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20 +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/regions-bound-missing-bound-in-impl.rs:42:30 | +LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { + | ^^^ ^^^ + | + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'_` differs between the trait and impl + --> $DIR/regions-bound-missing-bound-in-impl.rs:13:21 + | +LL | pub trait Foo<'a, 't> { + | --------------------- in this trait... +... LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); - | ---------------- - | | | | - | | | this bound might be missing in the impl - | | this bound might be missing in the impl - | lifetimes in impl do not match this method in trait + | ^^ -- this lifetime bound makes `'b` early-bound + | | + | `'b` is early-bound +... +LL | impl<'a, 't> Foo<'a, 't> for &'a isize { + | -------------------------------------- in this impl... ... LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { - | ^ lifetimes do not match method in trait + | ^^^ `'_` is late-bound +note: `'_` differs between the trait and impl + --> $DIR/regions-bound-missing-bound-in-impl.rs:13:27 + | +LL | pub trait Foo<'a, 't> { + | --------------------- in this trait... +... +LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + | ^^ -- this lifetime bound makes `'d` early-bound + | | + | `'d` is early-bound +... +LL | impl<'a, 't> Foo<'a, 't> for &'a isize { + | -------------------------------------- in this impl... +... +LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { + | ^^^ `'_` is late-bound error[E0276]: impl has stricter requirements than trait --> $DIR/regions-bound-missing-bound-in-impl.rs:49:26 diff --git a/tests/ui/error-codes/E0195.rs b/tests/ui/error-codes/E0195.rs index 8280901b1cd5..66968f70bd9e 100644 --- a/tests/ui/error-codes/E0195.rs +++ b/tests/ui/error-codes/E0195.rs @@ -1,14 +1,25 @@ trait Trait { +//~^ NOTE in this trait... +//~| NOTE in this trait... fn bar<'a,'b:'a>(x: &'a str, y: &'b str); - //~^ NOTE lifetimes in impl do not match this associated function in trait + //~^ NOTE `'a` is early-bound + //~| NOTE this lifetime bound makes `'a` early-bound + //~| NOTE `'b` is early-bound + //~| NOTE this lifetime bound makes `'b` early-bound } struct Foo; impl Trait for Foo { - fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195 - //~^ NOTE lifetimes do not match associated function in trait - //~| NOTE this bound might be missing in the impl +//~^ NOTE in this impl... +//~| NOTE in this impl... + fn bar<'a,'b>(x: &'a str, y: &'b str) { + //~^ ERROR E0195 + //~| NOTE `'a` differs between the trait and impl + //~| NOTE `'a` is late-bound + //~| NOTE `'b` differs between the trait and impl + //~| NOTE `'b` is late-bound + //~| NOTE lifetime parameters differ in whether they are early- or late-bound } } diff --git a/tests/ui/error-codes/E0195.stderr b/tests/ui/error-codes/E0195.stderr index 6eac910bedfb..d0295b364347 100644 --- a/tests/ui/error-codes/E0195.stderr +++ b/tests/ui/error-codes/E0195.stderr @@ -1,14 +1,42 @@ -error[E0195]: lifetime parameters or bounds on associated function `bar` do not match the trait declaration - --> $DIR/E0195.rs:9:11 +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/E0195.rs:16:12 | +LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { + | ^^ ^^ + | + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'a` differs between the trait and impl + --> $DIR/E0195.rs:4:12 + | +LL | trait Trait { + | ----------- in this trait... +... LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); - | ---------- - | | | - | | this bound might be missing in the impl - | lifetimes in impl do not match this associated function in trait + | ^^ -- this lifetime bound makes `'a` early-bound + | | + | `'a` is early-bound +... +LL | impl Trait for Foo { + | ------------------ in this impl... ... LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { - | ^^^^^^^ lifetimes do not match associated function in trait + | ^^ `'a` is late-bound +note: `'b` differs between the trait and impl + --> $DIR/E0195.rs:4:15 + | +LL | trait Trait { + | ----------- in this trait... +... +LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); + | ^^ -- this lifetime bound makes `'b` early-bound + | | + | `'b` is early-bound +... +LL | impl Trait for Foo { + | ------------------ in this impl... +... +LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { + | ^^ `'b` is late-bound error: aborting due to 1 previous error diff --git a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr index e26cb22163f1..f8a6252f991e 100644 --- a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr +++ b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr @@ -10,26 +10,53 @@ LL | fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a; LL | fn foo<'a, K>(self, _: (), _: K) where { | ^^^^^^^ lifetimes do not match method in trait -error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:11 +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:12 | -LL | fn foo<'a>(&self, state: &'a State) -> &'a T - | ---- lifetimes in impl do not match this method in trait -LL | where -LL | T: 'a; - | -- this bound might be missing in the impl -... LL | fn foo<'a>(&self, state: &'a State) -> &'a T { - | ^^^^ lifetimes do not match method in trait - -error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:11 + | ^^ | -LL | fn foo<'a>(&'a self) {} - | ---- lifetimes in impl do not match this method in trait + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'a` differs between the trait and impl + --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:14:12 + | +LL | trait Foo { + | ------------ in this trait... +LL | fn foo<'a>(&self, state: &'a State) -> &'a T + | ^^ `'a` is early-bound +LL | where +LL | T: 'a; + | -- this lifetime bound makes `'a` early-bound ... +LL | / impl Foo for F +LL | | where +LL | | F: Fn(&State) -> &T, + | |________________________- in this impl... +LL | { +LL | fn foo<'a>(&self, state: &'a State) -> &'a T { + | ^^ `'a` is late-bound + +error[E0195]: lifetime parameters do not match the trait definition + --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:12 + | LL | fn foo<'a: 'a>(&'a self) {} - | ^^^^^^^^ lifetimes do not match method in trait + | ^^ + | + = note: lifetime parameters differ in whether they are early- or late-bound +note: `'a` differs between the trait and impl + --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:29:12 + | +LL | trait Bar { + | --------- in this trait... +LL | fn foo<'a>(&'a self) {} + | ^^ `'a` is late-bound +... +LL | impl Bar for () { + | --------------- in this impl... +LL | fn foo<'a: 'a>(&'a self) {} + | ^^ -- this lifetime bound makes `'a` early-bound + | | + | `'a` is early-bound error: aborting due to 3 previous errors From aeb70c710abd019fabafb85536a4fcabfbef0d5d Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 7 May 2025 18:45:58 +0000 Subject: [PATCH 234/262] rustdoc-json: Remove newlines from attributes --- src/librustdoc/clean/types.rs | 6 +++++- tests/rustdoc-json/attrs/automatically_derived.rs | 2 +- tests/rustdoc-json/attrs/export_name_2021.rs | 2 +- tests/rustdoc-json/attrs/export_name_2024.rs | 2 +- tests/rustdoc-json/attrs/must_use.rs | 4 ++-- tests/rustdoc-json/attrs/no_mangle_2021.rs | 2 +- tests/rustdoc-json/attrs/no_mangle_2024.rs | 2 +- tests/rustdoc-json/attrs/non_exhaustive.rs | 6 +++--- tests/rustdoc-json/keyword_private.rs | 4 ++-- 9 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bbe11bf56af3..15890fff0c33 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -786,7 +786,11 @@ impl Item { // because it isn't public API. None } - _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)), + _ => Some({ + let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr); + assert_eq!(s.pop(), Some('\n')); + s + }), } } else if attr.has_any_name(ALLOWED_ATTRIBUTES) { Some( diff --git a/tests/rustdoc-json/attrs/automatically_derived.rs b/tests/rustdoc-json/attrs/automatically_derived.rs index 6c90d6386499..4e1ab3d145e5 100644 --- a/tests/rustdoc-json/attrs/automatically_derived.rs +++ b/tests/rustdoc-json/attrs/automatically_derived.rs @@ -9,5 +9,5 @@ impl Default for Manual { } } -//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]\n"]' +//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]' //@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]' diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs index 4e6526419bdb..254e9f6ef5bf 100644 --- a/tests/rustdoc-json/attrs/export_name_2021.rs +++ b/tests/rustdoc-json/attrs/export_name_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' #[export_name = "altered"] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs index f6a2a92b5bcd..8129c109306c 100644 --- a/tests/rustdoc-json/attrs/export_name_2024.rs +++ b/tests/rustdoc-json/attrs/export_name_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024 // is still `#[export_name = ..]` without the `unsafe` attribute wrapper. -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]\n"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' #[unsafe(export_name = "altered")] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs index 20696dce7121..64df8e5f509f 100644 --- a/tests/rustdoc-json/attrs/must_use.rs +++ b/tests/rustdoc-json/attrs/must_use.rs @@ -1,9 +1,9 @@ #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]\n"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]"]' #[must_use] pub fn example() -> impl Iterator {} -//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]\n"]' +//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' #[must_use = "does nothing if you do not use it"] pub fn explicit_message() -> impl Iterator {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs index 10a372572ae5..588be7256db5 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2021.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' #[no_mangle] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs index 8f3a14cbecbf..0d500e20e6c5 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2024.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024 // is still `#[no_mangle]` without the `unsafe` attribute wrapper. -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]\n"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' #[unsafe(no_mangle)] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs index 3064b86422d1..b95f1a8171fd 100644 --- a/tests/rustdoc-json/attrs/non_exhaustive.rs +++ b/tests/rustdoc-json/attrs/non_exhaustive.rs @@ -1,18 +1,18 @@ #![no_std] -//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]\n"]' +//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] pub enum MyEnum { First, } pub enum NonExhaustiveVariant { - //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]\n"]' + //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] Variant(i64), } -//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]\n"]' +//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] pub struct MyStruct { pub x: i64, diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs index 5e9a2c101636..fea546c9fb60 100644 --- a/tests/rustdoc-json/keyword_private.rs +++ b/tests/rustdoc-json/keyword_private.rs @@ -5,7 +5,7 @@ //@ !has "$.index[?(@.name=='match')]" //@ has "$.index[?(@.name=='foo')]" -//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]\n"]' +//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]' //@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"' #[doc(keyword = "match")] /// this is a test! @@ -13,7 +13,7 @@ pub mod foo {} //@ !has "$.index[?(@.name=='break')]" //@ has "$.index[?(@.name=='bar')]" -//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]\n"]' +//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]' //@ is "$.index[?(@.name=='bar')].docs" '"hello"' #[doc(keyword = "break")] /// hello From 75ca6c621e08eb7252bb542b9264e7ab7a8fc4e1 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 7 May 2025 10:56:00 -0700 Subject: [PATCH 235/262] [win][arm64] Disable MSVC Linker 'Arm Hazard' warning --- .../src/spec/targets/aarch64_pc_windows_msvc.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index 98d78520c983..0d25b19f3fcf 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -1,10 +1,15 @@ -use crate::spec::{Target, TargetMetadata, base}; +use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); base.features = "+v8a,+neon,+fp-armv8".into(); + // MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see + // https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM. + // Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning. + base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/arm64hazardfree"]); + Target { llvm_target: "aarch64-pc-windows-msvc".into(), metadata: TargetMetadata { From 38e3fa61f634e37ca99f7d91b770d38886c9e813 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 7 May 2025 20:31:47 +0100 Subject: [PATCH 236/262] style: Never break within a nullary function call `func()` or a unit literal `()` --- src/doc/style-guide/src/editions.md | 4 ++++ src/doc/style-guide/src/expressions.md | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index 19e62c4867c9..81b7ff50052a 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -26,6 +26,10 @@ edition). Not all Rust editions have corresponding changes to the Rust style. For instance, Rust 2015, Rust 2018, and Rust 2021 all use the same style edition. +## Rust next style edition + +- Never break within a nullary function call `func()` or a unit literal `()`. + ## Rust 2024 style edition This style guide describes the Rust 2024 style edition. The Rust 2024 style diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 031e59d86e1d..9df5d7d18edb 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -183,6 +183,10 @@ let f = Foo { }; ``` +## Unit literals + +Never break between the opening and closing parentheses of the `()` unit literal. + ## Tuple literals Use a single-line form where possible. Do not put spaces between the opening @@ -377,6 +381,11 @@ Do put a space between an argument, and the comma which precedes it. Prefer not to break a line in the callee expression. +For a function call with no arguments (a nullary function call like `func()`), +never break within the parentheses, and never put a space between the +parentheses. Always write a nullary function call as a single-line call, never +a multi-line call. + ### Single-line calls Do not put a space between the function name and open paren, between the open From 5913e55dfc3c473f6c28f5a341850574aff1f685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 7 May 2025 20:52:08 +0200 Subject: [PATCH 237/262] Add `DefPathData::OpaqueLifetime` to avoid conflicts for remapped opaque lifetimes --- compiler/rustc_hir/src/definitions.rs | 15 ++++++----- .../src/collect/resolve_bound_vars.rs | 10 +++---- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 1 + .../lifetime-def-path-conflict-40731.rs | 16 ++++++++++++ .../lifetime-def-path-conflict-40731.stderr | 26 +++++++++++++++++++ 6 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs create mode 100644 tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 98b41187f114..f93b9e5af534 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -309,6 +309,8 @@ pub enum DefPathData { /// An existential `impl Trait` type node. /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name. OpaqueTy, + /// Used for remapped captured lifetimes in an existential `impl Trait` type node. + OpaqueLifetime(Symbol), /// An anonymous associated type from an RPITIT. The symbol refers to the name of the method /// that defined the type. AnonAssocTy(Symbol), @@ -445,7 +447,8 @@ impl DefPathData { pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), + TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) + | OpaqueLifetime(name) => Some(name), Impl | ForeignMod @@ -465,9 +468,8 @@ impl DefPathData { fn hashed_symbol(&self) -> Option { use self::DefPathData::*; match *self { - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => { - Some(name) - } + TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) + | OpaqueLifetime(name) => Some(name), Impl | ForeignMod @@ -486,9 +488,8 @@ impl DefPathData { pub fn name(&self) -> DefPathDataName { use self::DefPathData::*; match *self { - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => { - DefPathDataName::Named(name) - } + TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) + | OpaqueLifetime(name) => DefPathDataName::Named(name), // Note that this does not show up in user print-outs. CrateRoot => DefPathDataName::Anon { namespace: kw::Crate }, Impl => DefPathDataName::Anon { namespace: kw::Impl }, 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 a89160785eb1..709446d09cd2 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -14,7 +14,7 @@ use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::definitions::DisambiguatorState; +use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node, @@ -1470,14 +1470,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { let mut captures = captures.borrow_mut(); let remapped = *captures.entry(lifetime).or_insert_with(|| { // `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once - // per `resolve_bound_vars` query. This is the only location that creates nested - // lifetime inside a opaque type. `::LifetimeNs(..)` is thus unique + // per `resolve_bound_vars` query. This is the only location that creates + // `OpaqueLifetime` paths. `::OpaqueLifetime(..)` is thus unique // to this query and duplicates within the query are handled by `self.disambiguator`. let feed = self.tcx.create_def( opaque_def_id, - Some(ident.name), - DefKind::LifetimeParam, None, + DefKind::LifetimeParam, + Some(DefPathData::OpaqueLifetime(ident.name)), &mut self.disambiguator, ); feed.def_span(ident.span); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index f7f354d12e8c..47831f2f4180 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -722,6 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { | hir::definitions::DefPathData::Use | hir::definitions::DefPathData::GlobalAsm | hir::definitions::DefPathData::MacroNs(..) + | hir::definitions::DefPathData::OpaqueLifetime(..) | hir::definitions::DefPathData::LifetimeNs(..) | hir::definitions::DefPathData::AnonAssocTy(..) => { bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1f45440eecfc..4a99ce09b39a 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -890,6 +890,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { | DefPathData::Impl | DefPathData::MacroNs(_) | DefPathData::LifetimeNs(_) + | DefPathData::OpaqueLifetime(_) | DefPathData::AnonAssocTy(..) => { bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data) } diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs new file mode 100644 index 000000000000..bfaa48585ef1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/140731 +// This tests that there's no def path conflict between the +// remapped lifetime and the lifetime present in the source. + +#![feature(impl_trait_in_assoc_type)] + +trait Trait<'a> {} + +impl<'a> Trait<'a> for u32 { + type Opq2 = impl for<'a> Trait<'a>; + //~^ ERROR: unconstrained opaque type + //~| ERROR: type `Opq2` is not a member of trait `Trait` + //~| ERROR: lifetime name `'a` shadows a lifetime name that is already in scope +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr new file mode 100644 index 000000000000..e1544c5911b9 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr @@ -0,0 +1,26 @@ +error[E0437]: type `Opq2` is not a member of trait `Trait` + --> $DIR/lifetime-def-path-conflict-40731.rs:10:5 + | +LL | type Opq2 = impl for<'a> Trait<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Trait` + +error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope + --> $DIR/lifetime-def-path-conflict-40731.rs:10:26 + | +LL | impl<'a> Trait<'a> for u32 { + | -- first declared here +LL | type Opq2 = impl for<'a> Trait<'a>; + | ^^ lifetime `'a` already in scope + +error: unconstrained opaque type + --> $DIR/lifetime-def-path-conflict-40731.rs:10:17 + | +LL | type Opq2 = impl for<'a> Trait<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Opq2` must be used in combination with a concrete type within the same impl + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0437, E0496. +For more information about an error, try `rustc --explain E0437`. From 34c42c8f314af939e2f28f46f96293642516aa97 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 7 May 2025 22:34:56 +0300 Subject: [PATCH 238/262] do not allow stage > 0 on `x fmt` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/format.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 9da8b27a9177..ca8414530a57 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -9,7 +9,7 @@ use std::sync::mpsc::SyncSender; use build_helper::git::get_git_modified_files; use ignore::WalkBuilder; -use crate::core::builder::Builder; +use crate::core::builder::{Builder, Kind}; use crate::utils::build_stamp::BuildStamp; use crate::utils::exec::command; use crate::utils::helpers::{self, t}; @@ -122,6 +122,11 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) { } pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { + if build.kind == Kind::Format && build.top_stage != 0 { + eprintln!("ERROR: `x fmt` only supports stage 0."); + crate::exit!(1); + } + if !paths.is_empty() { eprintln!( "fmt error: path arguments are no longer accepted; use `--all` to format everything" From 1799f5f8a93c0bcef6c52ea9074dd69f8183e4f1 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 7 May 2025 21:29:03 +0000 Subject: [PATCH 239/262] triagebot: Better message for changes to `tests/rustdoc-json` --- triagebot.toml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 422996cb200d..915c409514c0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1001,7 +1001,15 @@ message = "This PR changes how GCC is built. Consider updating src/bootstrap/dow message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge." [mentions."tests/rustdoc-json"] -cc = ["@aDotInTheVoid"] +message = """ +These commits modify `test/rustdoc-json`. +rustdoc-json is a **public** (but unstable) interface. + +Please ensure that if you've changed the output: +- It's intentional. +- The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary. +""" +cc = ["@aDotInTheVoid", "@obi1kenobi"] [mentions."tests/ui/deriving/deriving-all-codegen.stdout"] message = "Changes to the code generated for builtin derived traits." From 1a18da56742f307644b831a749b931072b805f4e Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 7 May 2025 23:23:36 +0300 Subject: [PATCH 240/262] implement `x run rustfmt` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/format.rs | 1 + src/bootstrap/src/core/build_steps/run.rs | 53 ++++++++++++++++++++ src/bootstrap/src/core/builder/mod.rs | 1 + 3 files changed, 55 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index ca8414530a57..93900a9043e7 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -124,6 +124,7 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) { pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { if build.kind == Kind::Format && build.top_stage != 0 { eprintln!("ERROR: `x fmt` only supports stage 0."); + eprintln!("HELP: Use `x run rustfmt` to run in-tree rustfmt."); crate::exit!(1); } diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 7ff385052940..0bba441c3fa2 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -420,3 +420,56 @@ impl Step for CoverageDump { cmd.run(builder); } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Rustfmt; + +impl Step for Rustfmt { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/rustfmt") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Rustfmt); + } + + fn run(self, builder: &Builder<'_>) { + let host = builder.build.build; + + // `x run` uses stage 0 by default but rustfmt does not work well with stage 0. + // Change the stage to 1 if it's not set explicitly. + let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 { + builder.top_stage + } else { + 1 + }; + + if stage == 0 { + eprintln!("rustfmt cannot be run at stage 0"); + eprintln!("HELP: Use `x fmt` to use stage 0 rustfmt."); + std::process::exit(1); + } + + let compiler = builder.compiler(stage, host); + let rustfmt_build = builder.ensure(tool::Rustfmt { compiler, target: host }); + + let mut rustfmt = tool::prepare_tool_cargo( + builder, + rustfmt_build.build_compiler, + Mode::ToolRustc, + host, + Kind::Run, + "src/tools/rustfmt", + SourceType::InTree, + &[], + ); + + rustfmt.args(["--bin", "rustfmt", "--"]); + rustfmt.args(builder.config.args()); + + rustfmt.into_cmd().run(builder); + } +} diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 15dc3380a39a..75cc5d3986b8 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1116,6 +1116,7 @@ impl<'a> Builder<'a> { run::FeaturesStatusDump, run::CyclicStep, run::CoverageDump, + run::Rustfmt, ), Kind::Setup => { describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor) From e85d014244da0c208bfbf6bfc60b89b1ecc831b0 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 7 May 2025 23:33:15 +0300 Subject: [PATCH 241/262] add change-entry for `x run rustfmt` Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index d926185ffaf1..1d0ea3ebf610 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -406,4 +406,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.", }, + ChangeInfo { + change_id: 140732, + severity: ChangeSeverity::Info, + summary: "`./x run` now supports running in-tree `rustfmt`, e.g., `./x run rustfmt -- --check /path/to/file.rs`.", + }, ]; From 52fcf33ed7de89647329f354cbd0045180a9d367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 8 May 2025 10:17:21 +0200 Subject: [PATCH 242/262] Remove unused dependency from opt-dist --- src/tools/opt-dist/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index b0db8346f7ed..279b19d50577 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -15,7 +15,6 @@ fs_extra = "1" camino = "1" tar = "0.4" xz = { version = "0.1", package = "xz2" } -serde = { version = "1", features = ["derive"] } serde_json = "1" glob = "0.3" tempfile = "3.5" From 34495f5895e187fe858e5f33c0bb5fe0a4d50efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 8 May 2025 10:18:17 +0200 Subject: [PATCH 243/262] Migrate `opt-dist` to edition 2024 --- Cargo.lock | 1 - src/tools/opt-dist/Cargo.toml | 2 +- src/tools/opt-dist/src/main.rs | 5 ++++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83d7a6a9ab13..fa0fa33ea75a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2567,7 +2567,6 @@ dependencies = [ "humansize", "humantime", "log", - "serde", "serde_json", "sysinfo", "tabled", diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index 279b19d50577..dfa884bc3f77 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "opt-dist" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] build_helper = { path = "../../build_helper" } diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index d5e6640fb430..1bb72431fe6c 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -361,7 +361,10 @@ fn execute_pipeline( fn main() -> anyhow::Result<()> { // Make sure that we get backtraces for easier debugging in CI - std::env::set_var("RUST_BACKTRACE", "1"); + unsafe { + // SAFETY: we are the only thread running at this point + std::env::set_var("RUST_BACKTRACE", "1"); + } env_logger::builder() .filter_level(LevelFilter::Info) From fc0f0a8add7a6df5b4fd754dd721f3d262874682 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 6 May 2025 22:30:52 +0200 Subject: [PATCH 244/262] Add tests for `-Zremap-path-scope` and paths in diagnostics with deps --- tests/ui/errors/auxiliary/trait-debuginfo.rs | 4 ++ tests/ui/errors/auxiliary/trait-diag.rs | 4 ++ tests/ui/errors/auxiliary/trait-macro.rs | 4 ++ tests/ui/errors/auxiliary/trait.rs | 1 + ...prefix-diagnostics.not-diag-in-deps.stderr | 17 ++++++ ...-diagnostics.only-debuginfo-in-deps.stderr | 17 ++++++ ...refix-diagnostics.only-diag-in-deps.stderr | 17 ++++++ ...efix-diagnostics.only-macro-in-deps.stderr | 17 ++++++ .../errors/remap-path-prefix-diagnostics.rs | 57 +++++++++++++++++++ ...-diagnostics.with-debuginfo-in-deps.stderr | 17 ++++++ ...refix-diagnostics.with-diag-in-deps.stderr | 17 ++++++ ...efix-diagnostics.with-macro-in-deps.stderr | 17 ++++++ 12 files changed, 189 insertions(+) create mode 100644 tests/ui/errors/auxiliary/trait-debuginfo.rs create mode 100644 tests/ui/errors/auxiliary/trait-diag.rs create mode 100644 tests/ui/errors/auxiliary/trait-macro.rs create mode 100644 tests/ui/errors/auxiliary/trait.rs create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.rs create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr create mode 100644 tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr diff --git a/tests/ui/errors/auxiliary/trait-debuginfo.rs b/tests/ui/errors/auxiliary/trait-debuginfo.rs new file mode 100644 index 000000000000..d5a0825fe6d1 --- /dev/null +++ b/tests/ui/errors/auxiliary/trait-debuginfo.rs @@ -0,0 +1,4 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=debuginfo + +pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/auxiliary/trait-diag.rs b/tests/ui/errors/auxiliary/trait-diag.rs new file mode 100644 index 000000000000..e07961a276a9 --- /dev/null +++ b/tests/ui/errors/auxiliary/trait-diag.rs @@ -0,0 +1,4 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=diagnostics + +pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/auxiliary/trait-macro.rs b/tests/ui/errors/auxiliary/trait-macro.rs new file mode 100644 index 000000000000..48673d04ee16 --- /dev/null +++ b/tests/ui/errors/auxiliary/trait-macro.rs @@ -0,0 +1,4 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=macro + +pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/auxiliary/trait.rs b/tests/ui/errors/auxiliary/trait.rs new file mode 100644 index 000000000000..0e7e5400aac5 --- /dev/null +++ b/tests/ui/errors/auxiliary/trait.rs @@ -0,0 +1 @@ +pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr new file mode 100644 index 000000000000..3ddff11798de --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr new file mode 100644 index 000000000000..85c781425b16 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr new file mode 100644 index 000000000000..792ea7925ad5 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-diag.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr new file mode 100644 index 000000000000..d13333d2e482 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-macro.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.rs b/tests/ui/errors/remap-path-prefix-diagnostics.rs new file mode 100644 index 000000000000..fac7e937cb0b --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.rs @@ -0,0 +1,57 @@ +// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency. +// +// We test different combinations with/without remap in deps, with/without remap in this +// crate but always in deps and always here but never in deps. + +//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps +//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps +//@ revisions: not-diag-in-deps + +//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped + +//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics +//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro +//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo +//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics + +//@[with-diag-in-deps] aux-build:trait-diag.rs +//@[with-macro-in-deps] aux-build:trait-macro.rs +//@[with-debuginfo-in-deps] aux-build:trait-debuginfo.rs +//@[only-diag-in-deps] aux-build:trait-diag.rs +//@[only-macro-in-deps] aux-build:trait-macro.rs +//@[only-debuginfo-in-deps] aux-build:trait-debuginfo.rs +//@[not-diag-in-deps] aux-build:trait.rs + +// The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically +// as the remapped revision will not begin with $SRC_DIR_REAL, +// so we have to do it ourselves. +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL" + +#[cfg(any(with_diag_in_deps, only_diag_in_deps))] +extern crate trait_diag as r#trait; + +#[cfg(any(with_macro_in_deps, only_macro_in_deps))] +extern crate trait_macro as r#trait; + +#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))] +extern crate trait_debuginfo as r#trait; + +#[cfg(not_diag_in_deps)] +extern crate r#trait as r#trait; + +struct A; + +impl r#trait::Trait for A {} +//[with-macro-in-deps]~^ ERROR `A` doesn't implement `std::fmt::Display` +//[with-debuginfo-in-deps]~^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-diag-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-macro-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display` +//[only-debuginfo-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display` + +//[with-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display` +//[not-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display` + +fn main() {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr new file mode 100644 index 000000000000..85c781425b16 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr new file mode 100644 index 000000000000..08f7fb2c7364 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> remapped/errors/auxiliary/trait-diag.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr new file mode 100644 index 000000000000..d13333d2e482 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr @@ -0,0 +1,17 @@ +error[E0277]: `A` doesn't implement `std::fmt::Display` + --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL + | +LL | impl r#trait::Trait for A {} + | ^ `A` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `A` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Trait` + --> $DIR/auxiliary/trait-macro.rs:LL:COL + | +LL | pub trait Trait: std::fmt::Display {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 082777e088a02c81f8e50853ec28a8bb53d762ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 8 May 2025 10:19:30 +0200 Subject: [PATCH 245/262] Do not deny warnings for fast try builds --- src/tools/opt-dist/src/environment.rs | 5 +++++ src/tools/opt-dist/src/exec.rs | 11 +++++++++-- src/tools/opt-dist/src/main.rs | 21 +++++++++++++-------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs index 9342d164be41..946e926a3c01 100644 --- a/src/tools/opt-dist/src/environment.rs +++ b/src/tools/opt-dist/src/environment.rs @@ -26,6 +26,7 @@ pub struct Environment { use_bolt: bool, shared_llvm: bool, run_tests: bool, + fast_try_build: bool, } impl Environment { @@ -106,6 +107,10 @@ impl Environment { pub fn run_tests(&self) -> bool { self.run_tests } + + pub fn is_fast_try_build(&self) -> bool { + self.fast_try_build + } } /// What is the extension of binary executables on this platform? diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs index deff69a7f9c0..64ce5cc37752 100644 --- a/src/tools/opt-dist/src/exec.rs +++ b/src/tools/opt-dist/src/exec.rs @@ -113,13 +113,16 @@ impl Bootstrap { "library/std", ]) .env("RUST_BACKTRACE", "full"); + let cmd = add_shared_x_flags(env, cmd); + Self { cmd, metrics_path } } pub fn dist(env: &Environment, dist_args: &[String]) -> Self { let metrics_path = env.build_root().join("build").join("metrics.json"); - let cmd = cmd(&dist_args.iter().map(|arg| arg.as_str()).collect::>()) - .env("RUST_BACKTRACE", "full"); + let args = dist_args.iter().map(|arg| arg.as_str()).collect::>(); + let cmd = cmd(&args).env("RUST_BACKTRACE", "full"); + let cmd = add_shared_x_flags(env, cmd); Self { cmd, metrics_path } } @@ -184,3 +187,7 @@ impl Bootstrap { Ok(()) } } + +fn add_shared_x_flags(env: &Environment, cmd: CmdBuilder) -> CmdBuilder { + if env.is_fast_try_build() { cmd.arg("--set").arg("rust.deny-warnings=false") } else { cmd } +} diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 1bb72431fe6c..d2827ec01ca7 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -95,7 +95,7 @@ enum EnvironmentCmd { #[arg(long)] benchmark_cargo_config: Vec, - /// Perform tests after final build if it's not a try build + /// Perform tests after final build if it's not a fast try build #[arg(long)] run_tests: bool, }, @@ -111,11 +111,14 @@ enum EnvironmentCmd { }, } -fn is_try_build() -> bool { +/// For a fast try build, we want to only build the bare minimum of components to get a +/// working toolchain, and not run any tests. +fn is_fast_try_build() -> bool { std::env::var("DIST_TRY_BUILD").unwrap_or_else(|_| "0".to_string()) != "0" } fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> { + let is_fast_try_build = is_fast_try_build(); let (env, args) = match args.env { EnvironmentCmd::Local { target_triple, @@ -144,6 +147,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> .skipped_tests(skipped_tests) .benchmark_cargo_config(benchmark_cargo_config) .run_tests(run_tests) + .fast_try_build(is_fast_try_build) .build()?; (env, shared.build_args) @@ -167,6 +171,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> .use_bolt(!is_aarch64) .skipped_tests(vec![]) .run_tests(true) + .fast_try_build(is_fast_try_build) .build()?; (env, shared.build_args) @@ -187,6 +192,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> .use_bolt(false) .skipped_tests(vec![]) .run_tests(true) + .fast_try_build(is_fast_try_build) .build()?; (env, shared.build_args) @@ -350,9 +356,8 @@ fn execute_pipeline( // After dist has finished, run a subset of the test suite on the optimized artifacts to discover // possible regressions. - // The tests are not executed for try builds, which can be in various broken states, so we don't - // want to gatekeep them with tests. - if !is_try_build() && env.run_tests() { + // The tests are not executed for fast try builds, which can be broken and might not pass them. + if !is_fast_try_build() && env.run_tests() { timer.section("Run tests", |_| run_tests(env))?; } @@ -396,9 +401,9 @@ fn main() -> anyhow::Result<()> { let (env, mut build_args) = create_environment(args).context("Cannot create environment")?; - // Skip components that are not needed for try builds to speed them up - if is_try_build() { - log::info!("Skipping building of unimportant components for a try build"); + // Skip components that are not needed for fast try builds to speed them up + if is_fast_try_build() { + log::info!("Skipping building of unimportant components for a fast try build"); for target in [ "rust-docs", "rustc-docs", From f9590399949c84eb8c2cb7115efaa58425e6b281 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 6 May 2025 22:59:49 +0200 Subject: [PATCH 246/262] Rework `-Zremap-path-scope` macro test with dependency check --- tests/ui/errors/auxiliary/file-debuginfo.rs | 11 +++++ tests/ui/errors/auxiliary/file-diag.rs | 11 +++++ tests/ui/errors/auxiliary/file-macro.rs | 11 +++++ tests/ui/errors/auxiliary/file.rs | 8 ++++ .../remap-path-prefix-macro.normal.run.stdout | 1 - ...-prefix-macro.not-macro-in-deps.run.stdout | 3 ++ ...ix-macro.only-debuginfo-in-deps.run.stdout | 3 ++ ...-prefix-macro.only-diag-in-deps.run.stdout | 3 ++ ...prefix-macro.only-macro-in-deps.run.stdout | 3 ++ tests/ui/errors/remap-path-prefix-macro.rs | 47 ++++++++++++++++--- ...ix-macro.with-debuginfo-in-deps.run.stdout | 3 ++ ...-prefix-macro.with-diag-in-deps.run.stdout | 3 ++ ...prefix-macro.with-macro-in-deps.run.stdout | 3 ++ ...h-prefix-macro.with-macro-scope.run.stdout | 1 - ...refix-macro.without-macro-scope.run.stdout | 1 - 15 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 tests/ui/errors/auxiliary/file-debuginfo.rs create mode 100644 tests/ui/errors/auxiliary/file-diag.rs create mode 100644 tests/ui/errors/auxiliary/file-macro.rs create mode 100644 tests/ui/errors/auxiliary/file.rs delete mode 100644 tests/ui/errors/remap-path-prefix-macro.normal.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout create mode 100644 tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout delete mode 100644 tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout delete mode 100644 tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout diff --git a/tests/ui/errors/auxiliary/file-debuginfo.rs b/tests/ui/errors/auxiliary/file-debuginfo.rs new file mode 100644 index 000000000000..08113ec26bfd --- /dev/null +++ b/tests/ui/errors/auxiliary/file-debuginfo.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=debuginfo + +#[macro_export] +macro_rules! my_file { + () => { file!() } +} + +pub fn file() -> &'static str { + file!() +} diff --git a/tests/ui/errors/auxiliary/file-diag.rs b/tests/ui/errors/auxiliary/file-diag.rs new file mode 100644 index 000000000000..f29c349f703b --- /dev/null +++ b/tests/ui/errors/auxiliary/file-diag.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=diagnostics + +#[macro_export] +macro_rules! my_file { + () => { file!() } +} + +pub fn file() -> &'static str { + file!() +} diff --git a/tests/ui/errors/auxiliary/file-macro.rs b/tests/ui/errors/auxiliary/file-macro.rs new file mode 100644 index 000000000000..11abc0549a7b --- /dev/null +++ b/tests/ui/errors/auxiliary/file-macro.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --remap-path-prefix={{src-base}}=remapped +//@ compile-flags: -Zremap-path-scope=macro + +#[macro_export] +macro_rules! my_file { + () => { file!() } +} + +pub fn file() -> &'static str { + file!() +} diff --git a/tests/ui/errors/auxiliary/file.rs b/tests/ui/errors/auxiliary/file.rs new file mode 100644 index 000000000000..63a7b3b58f0f --- /dev/null +++ b/tests/ui/errors/auxiliary/file.rs @@ -0,0 +1,8 @@ +#[macro_export] +macro_rules! my_file { + () => { file!() } +} + +pub fn file() -> &'static str { + file!() +} diff --git a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout b/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout deleted file mode 100644 index 3bbdcbb8655b..000000000000 --- a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout +++ /dev/null @@ -1 +0,0 @@ -remapped/errors/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout new file mode 100644 index 000000000000..13d4611ae543 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = remapped/errors/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file.rs +file!() = remapped/errors/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout new file mode 100644 index 000000000000..b2c62ac88c04 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-debuginfo.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout new file mode 100644 index 000000000000..e64cc0723619 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-diag.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout new file mode 100644 index 000000000000..b1a93a5bc1ea --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = remapped/errors/auxiliary/file-macro.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.rs b/tests/ui/errors/remap-path-prefix-macro.rs index 665156027c99..3e93843f9164 100644 --- a/tests/ui/errors/remap-path-prefix-macro.rs +++ b/tests/ui/errors/remap-path-prefix-macro.rs @@ -1,12 +1,47 @@ +// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency. +// +// We test different combinations with/without remap in deps, with/without remap in +// this crate but always in deps and always here but never in deps. + //@ run-pass //@ check-run-results -//@ revisions: normal with-macro-scope without-macro-scope -//@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ [with-macro-scope]compile-flags: -Zremap-path-scope=macro,diagnostics -//@ [without-macro-scope]compile-flags: -Zremap-path-scope=diagnostics -// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file. +//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps +//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps +//@ revisions: not-macro-in-deps + +//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped +//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped + +//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics +//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro +//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo +//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro + +//@[with-diag-in-deps] aux-build:file-diag.rs +//@[with-macro-in-deps] aux-build:file-macro.rs +//@[with-debuginfo-in-deps] aux-build:file-debuginfo.rs +//@[only-diag-in-deps] aux-build:file-diag.rs +//@[only-macro-in-deps] aux-build:file-macro.rs +//@[only-debuginfo-in-deps] aux-build:file-debuginfo.rs +//@[not-macro-in-deps] aux-build:file.rs + +#[cfg(any(with_diag_in_deps, only_diag_in_deps))] +extern crate file_diag as file; + +#[cfg(any(with_macro_in_deps, only_macro_in_deps))] +extern crate file_macro as file; + +#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))] +extern crate file_debuginfo as file; + +#[cfg(not_macro_in_deps)] +extern crate file; fn main() { - println!("{}", file!()); + println!("file::my_file!() = {}", file::my_file!()); + println!("file::file() = {}", file::file()); + println!("file!() = {}", file!()); } diff --git a/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout new file mode 100644 index 000000000000..b2c62ac88c04 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-debuginfo.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout new file mode 100644 index 000000000000..e64cc0723619 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = $DIR/remap-path-prefix-macro.rs +file::file() = $DIR/auxiliary/file-diag.rs +file!() = $DIR/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout new file mode 100644 index 000000000000..5c1781dda161 --- /dev/null +++ b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout @@ -0,0 +1,3 @@ +file::my_file!() = remapped/errors/remap-path-prefix-macro.rs +file::file() = remapped/errors/auxiliary/file-macro.rs +file!() = remapped/errors/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout deleted file mode 100644 index 3bbdcbb8655b..000000000000 --- a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout +++ /dev/null @@ -1 +0,0 @@ -remapped/errors/remap-path-prefix-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout deleted file mode 100644 index 642823fec86a..000000000000 --- a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout +++ /dev/null @@ -1 +0,0 @@ -$DIR/remap-path-prefix-macro.rs From f501775ec8af20bad208ad9b5772342180696d85 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 26 Apr 2025 13:20:17 -0400 Subject: [PATCH 247/262] Indicate that the warning on black_box is a general property of Rust And note that the same limitation applies to all LLVM-based compilers Co-authored-by: Ralf Jung --- library/core/src/hint.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 1ca23ab6eea6..207b6c9b71f0 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -320,6 +320,10 @@ pub fn spin_loop() { /// This also means that this function does not offer any guarantees for cryptographic or security /// purposes. /// +/// This limitation is not specific to `black_box`; there is no mechanism in the entire Rust +/// language that can provide the guarantees required for constant-time cryptography. +/// (There is also no such mechanism in LLVM, so the same is true for every other LLVM-based compiler.) +/// /// /// /// [`std::convert::identity`]: crate::convert::identity From c0f0b5157f89dad5169a75d2475be408d800aafa Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 8 May 2025 21:06:45 +0800 Subject: [PATCH 248/262] Add ui test for for-loops-over-falibles Signed-off-by: xizheyin --- .../macro-issue-140747.rs | 10 ++++++ .../macro-issue-140747.stderr | 32 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs create mode 100644 tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs new file mode 100644 index 000000000000..0e6b88cbdc08 --- /dev/null +++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs @@ -0,0 +1,10 @@ +#![forbid(for_loops_over_fallibles)] + +fn main() { + macro_rules! x { + () => { + None:: //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles] + }; + } + for _ in x! {} {} +} diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr new file mode 100644 index 000000000000..1dc5f3207734 --- /dev/null +++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr @@ -0,0 +1,32 @@ +error: for loop over an `Option`. This is more readably written as an `if let` statement + --> $DIR/macro-issue-140747.rs:6:13 + | +LL | None:: + | ^^^^^^^^^^^ +... +LL | for _ in x! {} {} + | ----- in this macro invocation + | +note: the lint level is defined here + --> $DIR/macro-issue-140747.rs:1:11 + | +LL | #![forbid(for_loops_over_fallibles)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info) +help: to check pattern in a loop use `while let` + | +LL ~ ) = +LL | }; +LL | } +LL ~ while let Some(_ in x! {} {} + | +help: consider using `if let` to clear intent + | +LL ~ ) = +LL | }; +LL | } +LL ~ if let Some(_ in x! {} {} + | + +error: aborting due to 1 previous error + From 88c1796384cca81ca80e728d45f6673f601493ff Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 8 May 2025 21:12:02 +0800 Subject: [PATCH 249/262] Use span before macro expansion in lint for-loops-over-falibles Signed-off-by: xizheyin --- .../src/for_loops_over_fallibles.rs | 12 ++++++----- .../macro-issue-140747.rs | 4 ++-- .../macro-issue-140747.stderr | 20 ++++++------------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 757fc1f58bd5..a56b753bda72 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let Some((pat, arg)) = extract_for_loop(expr) else { return }; + let arg_span = arg.span.source_callsite(); + let ty = cx.typeck_results().expr_ty(arg); let (adt, args, ref_mutability) = match ty.kind() { @@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span) { ForLoopsOverFalliblesLoopSub::RemoveNext { - suggestion: recv.span.between(arg.span.shrink_to_hi()), + suggestion: recv.span.between(arg_span.shrink_to_hi()), recv_snip, } } else { ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), - end_span: pat.span.between(arg.span), + end_span: pat.span.between(arg_span), var, } }; let question_mark = suggest_question_mark(cx, adt, args, expr.span) - .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() }); + .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() }); let suggestion = ForLoopsOverFalliblesSuggestion { var, start_span: expr.span.with_hi(pat.span.lo()), - end_span: pat.span.between(arg.span), + end_span: pat.span.between(arg_span), }; cx.emit_span_lint( FOR_LOOPS_OVER_FALLIBLES, - arg.span, + arg_span, ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion }, ); } diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs index 0e6b88cbdc08..33a89ced963e 100644 --- a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs +++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs @@ -3,8 +3,8 @@ fn main() { macro_rules! x { () => { - None:: //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles] + None:: }; } - for _ in x! {} {} + for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles] } diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr index 1dc5f3207734..550d26045fbc 100644 --- a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr +++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr @@ -1,31 +1,23 @@ error: for loop over an `Option`. This is more readably written as an `if let` statement - --> $DIR/macro-issue-140747.rs:6:13 + --> $DIR/macro-issue-140747.rs:9:14 | -LL | None:: - | ^^^^^^^^^^^ -... LL | for _ in x! {} {} - | ----- in this macro invocation + | ^^^^^ | note: the lint level is defined here --> $DIR/macro-issue-140747.rs:1:11 | LL | #![forbid(for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info) help: to check pattern in a loop use `while let` | -LL ~ ) = -LL | }; -LL | } -LL ~ while let Some(_ in x! {} {} +LL - for _ in x! {} {} +LL + while let Some(_) = x! {} {} | help: consider using `if let` to clear intent | -LL ~ ) = -LL | }; -LL | } -LL ~ if let Some(_ in x! {} {} +LL - for _ in x! {} {} +LL + if let Some(_) = x! {} {} | error: aborting due to 1 previous error From 41ff588c70109d1ebaeed1cbb15769889158c35e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 May 2025 15:17:47 +0200 Subject: [PATCH 250/262] Make `rustdoc-tempdir-removal` run-make tests work on other platforms than linux --- tests/run-make/rustdoc-tempdir-removal/rmake.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/run-make/rustdoc-tempdir-removal/rmake.rs b/tests/run-make/rustdoc-tempdir-removal/rmake.rs index bd87f05b7cf5..9ad369ae5b10 100644 --- a/tests/run-make/rustdoc-tempdir-removal/rmake.rs +++ b/tests/run-make/rustdoc-tempdir-removal/rmake.rs @@ -1,14 +1,22 @@ // This test ensures that no temporary folder is "left behind" when doctests fail for any reason. -//@ only-linux +//@ ignore-cross-compile use std::path::Path; use run_make_support::{path, rfs, rustdoc}; fn run_doctest_and_check_tmpdir(tmp_dir: &Path, doctest: &str, edition: &str) { - let output = - rustdoc().input(doctest).env("TMPDIR", tmp_dir).arg("--test").edition(edition).run_fail(); + let mut runner = rustdoc(); + runner.input(doctest).arg("--test").edition(edition); + let output = if cfg!(unix) { + runner.env("TMPDIR", tmp_dir) + } else if cfg!(windows) { + runner.env("TEMP", tmp_dir).env("TMP", tmp_dir) + } else { + panic!("unsupported OS") + } + .run_fail(); output.assert_exit_code(101).assert_stdout_contains( "test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out", From a278f8dcea893d3083222e5c168ecfab200e1f4c Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 8 May 2025 14:28:10 +0100 Subject: [PATCH 251/262] Add release notes for 1.87.0 --- RELEASES.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 0948eb85192e..1a77c33b9957 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,169 @@ +Version 1.87.0 (2025-05-15) +========================== + + + +Language +-------- +- [Stabilize `asm_goto` feature](https://github.com/rust-lang/rust/pull/133870) +- [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `~`, `-`, and `*`}](https://github.com/rust-lang/rust/pull/134900). +- [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](https://github.com/rust-lang/rust/pull/135480) +- [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](https://github.com/rust-lang/rust/pull/138128) + + + +Compiler +-------- +- [x86: make SSE2 required for i686 targets and use it to pass SIMD types](https://github.com/rust-lang/rust/pull/135408) + + + +Platform Support +---------------- +- [Remove `i586-pc-windows-msvc` target](https://github.com/rust-lang/rust/pull/137957) + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + +[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html + + + +Libraries +--------- +- [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154) +- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375) +- [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080) +- [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933) +- Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717) +- [Undeprecate `env::home_dir`](https://github.com/rust-lang/rust/pull/137327) +- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449) +- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](https://github.com/rust-lang/rust/pull/138162) + + + +Stabilized APIs +--------------- + +- [`Vec::extract_if`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.extract_if) +- [`vec::ExtractIf`](https://doc.rust-lang.org/nightly/std/vec/struct.ExtractIf.html) +- [`LinkedList::extract_if`](https://doc.rust-lang.org/nightly/std/collections/struct.LinkedList.html#method.extract_if) +- [`linked_list::ExtractIf`](https://doc.rust-lang.org/nightly/std/collections/linked_list/struct.ExtractIf.html) +- [`<[T]>::split_off`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off) +- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_mut) +- [`<[T]>::split_off_first`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first) +- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first_mut) +- [`<[T]>::split_off_last`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last) +- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last_mut) +- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within) +- [`os_str::Display`](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.Display.html) +- [`OsString::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsString.html#method.display) +- [`OsStr::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsStr.html#method.display) +- [`io::pipe`](https://doc.rust-lang.org/nightly/std/io/fn.pipe.html) +- [`io::PipeReader`](https://doc.rust-lang.org/nightly/std/io/struct.PipeReader.html) +- [`io::PipeWriter`](https://doc.rust-lang.org/nightly/std/io/struct.PipeWriter.html) +- [`impl From for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle) +- [`impl From for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle) +- [`impl From for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html) +- [`impl From for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio) +- [`impl From for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd) +- [`impl From for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd) +- [`Box>::write`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.write) +- [`impl TryFrom> for String`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String) + +These APIs are now stable in const contexts: + +- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned) +- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned) +- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned-1) +- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned-1) +- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.offset_from_unsigned) +- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned) +- [`::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.cast_signed) +- [`NonZero::::cast_signed`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_signed-5). +- [`::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.cast_signed). +- [`NonZero::::cast_unsigned`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_unsigned-5). +- [`::is_multiple_of`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.is_multiple_of) +- [`::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shl) +- [`::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shr) +- [`::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shl) +- [`::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shr) +- [`::from_utf8`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8) +- [`::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_mut) +- [`::from_utf8_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked) +- [`::from_utf8_unchecked_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked_mut) +- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/str/fn.from_utf8_mut.html) +- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice) +- [`SocketAddr::set_ip`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_ip) +- [`SocketAddr::set_port`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_port), +- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_ip) +- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_port), +- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_ip) +- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_port) +- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_flowinfo) +- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_scope_id) +- [`char::is_digit`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_digit) +- [`char::is_whitespace`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_whitespace) +- [`::midpoint`](https://doc.rust-lang.org/std/primitive.isize.html#method.midpoint) +- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened) +- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened_mut) +- [`String::into_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.into_bytes) +- [`String::as_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str) +- [`String::capacity`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.capacity) +- [`String::as_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_bytes) +- [`String::len`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.len) +- [`String::is_empty`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.is_empty) +- [`String::as_mut_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str) +- [`String::as_mut_vec`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_vec) +- [`Vec::as_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_ptr) +- [`Vec::as_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice) +- [`Vec::capacity`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.capacity) +- [`Vec::len`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.len) +- [`Vec::is_empty`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.is_empty) +- [`Vec::as_mut_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice) +- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_ptr) + + + +Cargo +----- +- [Add terminal integration via ANSI OSC 9;4 sequences](https://github.com/rust-lang/cargo/pull/14615/) +- [chore: bump openssl to v3](https://github.com/rust-lang/cargo/pull/15232/) +- [feat(package): add --exclude-lockfile flag](https://github.com/rust-lang/cargo/pull/15234/) + + + +Compatibility Notes +------------------- +- [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](https://github.com/rust-lang/rust/pull/127581) +- [Unstable fields are now always considered to be inhabited](https://github.com/rust-lang/rust/pull/133889) +- [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](https://github.com/rust-lang/rust/pull/134900) +- [Make `Debug` impl of raw pointers print metadata if present](https://github.com/rust-lang/rust/pull/135080) +- [Warn against function pointers using unsupported ABI strings in dependencies](https://github.com/rust-lang/rust/pull/135767) +- [Associated types on `dyn` types are no longer deduplicated](https://github.com/rust-lang/rust/pull/136458) +- [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](https://github.com/rust-lang/rust/pull/136490) +- [Make `ptr_cast_add_auto_to_object` lint into hard error](https://github.com/rust-lang/rust/pull/136764) +- Many `std::arch` intrinsics are now safe to call in some contexts, there may now be new `unused_unsafe` warnings in existing codebases. +- [Limit `width` and `precision` formatting options to 16 bits on all targets](https://github.com/rust-lang/rust/pull/136932) +- [Turn order dependent trait objects future incompat warning into a hard error](https://github.com/rust-lang/rust/pull/136968) +- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449) +- [Windows: The standard library no longer links `advapi32`, except on win7.](https://github.com/rust-lang/rust/pull/138233) Code such as C libraries that were relying on this assumption may need to explicitly link advapi32. +- [Proc macros can no longer observe expanded `cfg(true)` attributes.](https://github.com/rust-lang/rust/pull/138844) +- [Start changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros. +- [Don't allow flattened format_args in const.](https://github.com/rust-lang/rust/pull/139624) + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Update to LLVM 20](https://github.com/rust-lang/rust/pull/135763) + + Version 1.86.0 (2025-04-03) ========================== From 4f9bb8c7353892b057ffbe382d680846ff2c01ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 8 May 2025 16:00:48 +0200 Subject: [PATCH 252/262] Mention fast try builds in the rustc-dev-guide --- src/doc/rustc-dev-guide/src/tests/ci.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index c04f296ba0b1..825be11c82a9 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -135,12 +135,16 @@ There are several use-cases for try builds: - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it passes the test suite executed by that job. -You can select which CI jobs will -be executed in the try build by adding lines containing `try-job: -` to the PR description. All such specified jobs will be executed -in the try build once the `@bors try` command is used on the PR. If no try -jobs are specified in this way, the jobs defined in the `try` section of -[`jobs.yml`] will be executed by default. +By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of +[`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build +will not execute any tests, and it will allow compilation warnings. It is useful when you want to +get an optimized toolchain as fast as possible, for a crater run or performance benchmarks, +even if it might not be working fully correctly. + +If you want to run a custom CI job in a try build and make sure that it passes all tests and does +not produce any compilation warnings, you can select CI jobs to be executed by adding lines +containing `try-job: ` to the PR description. All such specified jobs will be executed +in the try build once the `@bors try` command is used on the PR. Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using From 9af6ee50ed8630590ed02ca1c284d07b65d84d10 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 8 May 2025 15:00:11 +0000 Subject: [PATCH 253/262] Structurally resolve in check_ref_cast and calc_adjust_mode --- compiler/rustc_hir_typeck/src/pat.rs | 26 +++++++++++++++-------- tests/ui/pattern/normalize-ty-in-range.rs | 24 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 tests/ui/pattern/normalize-ty-in-range.rs diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f9502153afdc..17d48184dd97 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &pat.kind { // Type checking these product-like types successfully always require // that the expected type be of those types and not reference types. - PatKind::Tuple(..) - | PatKind::Range(..) - | PatKind::Slice(..) => AdjustMode::peel_all(), + PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(), // When checking an explicit deref pattern, only peel reference types. // FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box // patterns may want `PeelKind::Implicit`, stopping on encountering a box. - | PatKind::Box(_) - | PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }, + PatKind::Box(_) | PatKind::Deref(_) => { + AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat } + } // A never pattern behaves somewhat like a literal or unit variant. PatKind::Never => AdjustMode::peel_all(), // For patterns with paths, how we peel the scrutinee depends on the path's resolution. @@ -679,7 +678,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self.tcx.features().deref_patterns() && !matches!(lt.kind, PatExprKind::Lit { .. }) { - span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind); + span_bug!( + lt.span, + "FIXME(deref_patterns): adjust mode unimplemented for {:?}", + lt.kind + ); } // Call `resolve_vars_if_possible` here for inline const blocks. let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)); @@ -687,17 +690,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.features().deref_patterns() { let mut peeled_ty = lit_ty; let mut pat_ref_layers = 0; - while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() { + while let ty::Ref(_, inner_ty, mutbl) = + *self.try_structurally_resolve_type(pat.span, peeled_ty).kind() + { // We rely on references at the head of constants being immutable. debug_assert!(mutbl.is_not()); pat_ref_layers += 1; peeled_ty = inner_ty; } - AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } } + AdjustMode::Peel { + kind: PeelKind::Implicit { until_adt: None, pat_ref_layers }, + } } else { if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() } } - }, + } // Ref patterns are complicated, we handle them in `check_pat_ref`. PatKind::Ref(..) @@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // be peeled to `str` while ty here is still `&str`, if we don't // err early here, a rather confusing unification error will be // emitted instead). + let ty = self.try_structurally_resolve_type(expr.span, ty); let fail = !(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error()); Some((fail, ty, expr.span)) diff --git a/tests/ui/pattern/normalize-ty-in-range.rs b/tests/ui/pattern/normalize-ty-in-range.rs new file mode 100644 index 000000000000..f0d22362608e --- /dev/null +++ b/tests/ui/pattern/normalize-ty-in-range.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . +// Make sure we structurally normalize in range pattern checking in HIR typeck. + +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = i32; +} + +fn main() { + const X: <() as Foo>::Bar = 0; + + match 0 { + X..=X => {} + _ => {} + } +} From c9a96eb37921998f5d3ba41be1a4e3758e7c113f Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 9 May 2025 00:00:52 +0800 Subject: [PATCH 254/262] Enable triagebot note functionality for rust-lang/rust See . --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 57153f1d98ab..b3a319037bd3 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1397,3 +1397,7 @@ compiletest = [ # Enable issue transfers within the org # Documentation at: https://forge.rust-lang.org/triagebot/transfer.html [transfer] + +# Enable `@rustbot note` functionality +# Documentation at: https://forge.rust-lang.org/triagebot/note.html +[note] From eff20bfd29c22cbb2a21b325b420f2cf3fef3ad0 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 9 May 2025 00:08:40 +0800 Subject: [PATCH 255/262] Fix `tests/rustdoc-json` path --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 57153f1d98ab..3f6cf2e5c4f4 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1002,7 +1002,7 @@ message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, [mentions."tests/rustdoc-json"] message = """ -These commits modify `test/rustdoc-json`. +These commits modify `tests/rustdoc-json`. rustdoc-json is a **public** (but unstable) interface. Please ensure that if you've changed the output: From 3b4c4938c56405ac5a8e28d33cc19cc85a3e6bda Mon Sep 17 00:00:00 2001 From: bendn Date: Thu, 8 May 2025 20:58:38 +0700 Subject: [PATCH 256/262] add signed integers to unnecessary_lints to ensure feature parity with clippy --- .../src/check_unnecessary_transmutes.rs | 27 ++++++++++ .../pass/shims/x86/intrinsics-x86-sse2.rs | 1 + .../transmute/unnecessary-transmutation.fixed | 9 ++++ .../ui/transmute/unnecessary-transmutation.rs | 9 ++++ .../unnecessary-transmutation.stderr | 54 ++++++++++++++----- 5 files changed, 86 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs index 4aff127908ee..8da17a056e31 100644 --- a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs +++ b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs @@ -55,18 +55,45 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> { }, // char → u32 (Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")), + // char (→ u32) → i32 + (Char, Int(IntTy::I32)) => err(format!("u32::from({arg}).cast_signed()")), // u32 → char (Uint(UintTy::U32), Char) => Error { sugg: format!("char::from_u32_unchecked({arg})"), help: Some("consider `char::from_u32(…).unwrap()`"), span, }, + // i32 → char + (Int(IntTy::I32), Char) => Error { + sugg: format!("char::from_u32_unchecked(i32::cast_unsigned({arg}))"), + help: Some("consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`"), + span, + }, // uNN → iNN (Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())), // iNN → uNN (Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())), + // fNN → xsize + (Float(ty), Uint(UintTy::Usize)) => { + err(format!("{}::to_bits({arg}) as usize", ty.name_str())) + } + (Float(ty), Int(IntTy::Isize)) => { + err(format!("{}::to_bits({arg}) as isize", ty.name_str())) + } + // fNN (→ uNN) → iNN + (Float(ty), Int(..)) => err(format!("{}::to_bits({arg}).cast_signed()", ty.name_str())), // fNN → uNN (Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())), + // xsize → fNN + (Uint(UintTy::Usize) | Int(IntTy::Isize), Float(ty)) => { + err(format!("{}::from_bits({arg} as _)", ty.name_str(),)) + } + // iNN (→ uNN) → fNN + (Int(int_ty), Float(ty)) => err(format!( + "{}::from_bits({}::cast_unsigned({arg}))", + ty.name_str(), + int_ty.name_str() + )), // uNN → fNN (Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())), // bool → { x8 } diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs index 7aaf9c2624f9..731d8b577637 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs @@ -1,5 +1,6 @@ // We're testing x86 target specific features //@only-target: x86_64 i686 +#![allow(unnecessary_transmutes)] #[cfg(target_arch = "x86")] use std::arch::x86::*; diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed index 1a0df143cc5f..bf7d769348aa 100644 --- a/tests/ui/transmute/unnecessary-transmutation.fixed +++ b/tests/ui/transmute/unnecessary-transmutation.fixed @@ -49,6 +49,10 @@ fn main() { //~^ ERROR let y: char = char::from_u32_unchecked(y); //~^ ERROR + let y: i32 = u32::from('🐱').cast_signed(); + //~^ ERROR + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); + //~^ ERROR let x: u16 = i16::cast_unsigned(8i16); //~^ ERROR @@ -72,6 +76,11 @@ fn main() { let y: u64 = f64::to_bits(2.0); //~^ ERROR + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); + //~^ ERROR + let y: i64 = f64::to_bits(1f64).cast_signed(); + //~^ ERROR + let z: bool = (1u8 == 1); //~^ ERROR let z: u8 = (z) as u8; diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs index 6b979263c56c..b9de529f1ccc 100644 --- a/tests/ui/transmute/unnecessary-transmutation.rs +++ b/tests/ui/transmute/unnecessary-transmutation.rs @@ -49,6 +49,10 @@ fn main() { //~^ ERROR let y: char = transmute(y); //~^ ERROR + let y: i32 = transmute('🐱'); + //~^ ERROR + let y: char = transmute(y); + //~^ ERROR let x: u16 = transmute(8i16); //~^ ERROR @@ -72,6 +76,11 @@ fn main() { let y: u64 = transmute(2.0); //~^ ERROR + let y: f64 = transmute(1i64); + //~^ ERROR + let y: i64 = transmute(1f64); + //~^ ERROR + let z: bool = transmute(1u8); //~^ ERROR let z: u8 = transmute(z); diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr index b661aa13c985..a19f1bebf16f 100644 --- a/tests/ui/transmute/unnecessary-transmutation.stderr +++ b/tests/ui/transmute/unnecessary-transmutation.stderr @@ -154,82 +154,108 @@ LL | let y: char = transmute(y); = help: consider `char::from_u32(…).unwrap()` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:53:22 + --> $DIR/unnecessary-transmutation.rs:52:22 + | +LL | let y: i32 = transmute('🐱'); + | ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🐱').cast_signed()` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:54:23 + | +LL | let y: char = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(i32::cast_unsigned(y))` + | + = help: consider `char::from_u32(i32::cast_unsigned(…)).unwrap()` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:57:22 | LL | let x: u16 = transmute(8i16); | ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:55:22 + --> $DIR/unnecessary-transmutation.rs:59:22 | LL | let x: i16 = transmute(x); | ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:57:22 + --> $DIR/unnecessary-transmutation.rs:61:22 | LL | let x: u32 = transmute(4i32); | ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:59:22 + --> $DIR/unnecessary-transmutation.rs:63:22 | LL | let x: i32 = transmute(x); | ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:61:22 + --> $DIR/unnecessary-transmutation.rs:65:22 | LL | let x: u64 = transmute(7i64); | ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:63:22 + --> $DIR/unnecessary-transmutation.rs:67:22 | LL | let x: i64 = transmute(x); | ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:66:22 + --> $DIR/unnecessary-transmutation.rs:70:22 | LL | let y: f32 = transmute(1u32); | ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:68:22 + --> $DIR/unnecessary-transmutation.rs:72:22 | LL | let y: u32 = transmute(y); | ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:70:22 + --> $DIR/unnecessary-transmutation.rs:74:22 | LL | let y: f64 = transmute(3u64); | ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:72:22 + --> $DIR/unnecessary-transmutation.rs:76:22 | LL | let y: u64 = transmute(2.0); | ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:75:23 + --> $DIR/unnecessary-transmutation.rs:79:22 + | +LL | let y: f64 = transmute(1i64); + | ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(i64::cast_unsigned(1i64))` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:81:22 + | +LL | let y: i64 = transmute(1f64); + | ^^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(1f64).cast_signed()` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:84:23 | LL | let z: bool = transmute(1u8); | ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:77:21 + --> $DIR/unnecessary-transmutation.rs:86:21 | LL | let z: u8 = transmute(z); | ^^^^^^^^^^^^ help: replace this with: `(z) as u8` error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:82:21 + --> $DIR/unnecessary-transmutation.rs:91:21 | LL | let z: i8 = transmute(z); | ^^^^^^^^^^^^ help: replace this with: `(z) as i8` -error: aborting due to 32 previous errors +error: aborting due to 36 previous errors From 0326a2c3158bd1905bf82861a6be26b2d106e9f3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 8 May 2025 20:07:23 +0200 Subject: [PATCH 257/262] bootstrap: more consistent use of `...` when citing configuration snippets --- src/bootstrap/src/bin/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index cbfe00a757ce..833f80279517 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -163,7 +163,7 @@ fn check_version(config: &Config) -> Option { msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n"); msg.push_str("NOTE: to silence this warning, "); msg.push_str(&format!( - "add `change-id = {latest_change_id}` or change-id = \"ignore\" at the top of `bootstrap.toml`" + "add `change-id = {latest_change_id}` or `change-id = \"ignore\"` at the top of `bootstrap.toml`" )); return Some(msg); } @@ -195,7 +195,7 @@ fn check_version(config: &Config) -> Option { msg.push_str("NOTE: to silence this warning, "); msg.push_str(&format!( - "update `bootstrap.toml` to use `change-id = {latest_change_id}` or change-id = \"ignore\" instead" + "update `bootstrap.toml` to use `change-id = {latest_change_id}` or `change-id = \"ignore\"` instead" )); if io::stdout().is_terminal() { From d951c41a684c886900477b7087c9de51ddba03bd Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 8 May 2025 13:08:31 -0700 Subject: [PATCH 258/262] Enable non-leaf Frame Pointers for Arm64 Windows --- .../src/spec/targets/aarch64_pc_windows_msvc.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index 0d25b19f3fcf..c5704c574483 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -1,10 +1,16 @@ -use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); base.features = "+v8a,+neon,+fp-armv8".into(); + // Microsoft recommends enabling frame pointers on Arm64 Windows. + // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers + // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW + // and other services. It must point to the previous {x29, x30} pair on the stack." + base.frame_pointer = FramePointer::NonLeaf; + // MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see // https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM. // Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning. From 0984db553ddd25c0d16ef68b91bd731825309ac5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 24 Apr 2025 11:56:44 +1000 Subject: [PATCH 259/262] Remove `Ident::empty`. All uses have been removed. And it's nonsensical: an identifier by definition has at least one char. The commits adds an is-non-empty assertion to `Ident::new` to enforce this, and converts some `Ident` constructions to use `Ident::new`. Adding the assertion requires making `Ident::new` and `Ident::with_dummy_span` non-const, which is no great loss. The commit amends a couple of places that do path splitting to ensure no empty identifiers are created. --- compiler/rustc_hir/src/hir/tests.rs | 23 ++++++----------- compiler/rustc_parse/src/parser/expr.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 4 +-- compiler/rustc_resolve/src/lib.rs | 25 +++++++++++++------ compiler/rustc_span/src/symbol.rs | 22 +++++++--------- src/librustdoc/clean/render_macro_matchers.rs | 2 +- .../passes/collect_intra_doc_links.rs | 21 +++++++++++----- 7 files changed, 54 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 18f8c523f9d3..8684adee29c9 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -50,21 +50,14 @@ fn trait_object_roundtrips() { } fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) { - let unambig = TyKind::TraitObject::<'_, ()>( - &[], - TaggedRef::new( - &const { - Lifetime { - hir_id: HirId::INVALID, - ident: Ident::new(sym::name, DUMMY_SP), - kind: LifetimeKind::Static, - source: LifetimeSource::Other, - syntax: LifetimeSyntax::Hidden, - } - }, - syntax, - ), - ); + let lt = Lifetime { + hir_id: HirId::INVALID, + ident: Ident::new(sym::name, DUMMY_SP), + kind: LifetimeKind::Static, + source: LifetimeSource::Other, + syntax: LifetimeSyntax::Hidden, + }; + let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(<, syntax)); let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) }; match unambig_to_ambig { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f3b53971b295..2a7910a6af4d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3828,7 +3828,7 @@ impl<'a> Parser<'a> { // Convert `label` -> `'label`, // so that nameres doesn't complain about non-existing label let label = format!("'{}", ident.name); - let ident = Ident { name: Symbol::intern(&label), span: ident.span }; + let ident = Ident::new(Symbol::intern(&label), ident.span); self.dcx().emit_err(errors::ExpectedLabelFoundIdent { span: ident.span, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index cb328022c76d..3460c53782f3 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -549,7 +549,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { source = module_path.pop().unwrap(); if rename.is_none() { // Keep the span of `self`, but the name of `foo` - ident = Ident { name: source.ident.name, span: self_span }; + ident = Ident::new(source.ident.name, self_span); } } } else { @@ -597,7 +597,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if let Some(crate_name) = crate_name { // `crate_name` should not be interpreted as relative. module_path.push(Segment::from_ident_and_id( - Ident { name: kw::PathRoot, span: source.ident.span }, + Ident::new(kw::PathRoot, source.ident.span), self.r.next_node_id(), )); source.ident.name = crate_name; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7e516d82df1d..4c47e9ed6992 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2157,13 +2157,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: ParentScope<'ra>, ) -> Option { - let mut segments = - Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident)); - if let Some(segment) = segments.first_mut() { - if segment.ident.name == kw::Empty { - segment.ident.name = kw::PathRoot; - } - } + let segments: Result, ()> = path_str + .split("::") + .enumerate() + .map(|(i, s)| { + let sym = if s.is_empty() { + if i == 0 { + // For a path like `::a::b`, use `kw::PathRoot` as the leading segment. + kw::PathRoot + } else { + return Err(()); // occurs in cases like `String::` + } + } else { + Symbol::intern(s) + }; + Ok(Segment::from_ident(Ident::with_dummy_span(sym))) + }) + .collect(); + let Ok(segments) = segments else { return None }; match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 40cec4083089..f2f6d1a3bcf8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2342,6 +2342,9 @@ pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, s #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)] pub struct Ident { + // `name` should never be the empty symbol. If you are considering that, + // you are probably conflating "empty identifer with "no identifier" and + // you should use `Option` instead. pub name: Symbol, pub span: Span, } @@ -2349,28 +2352,21 @@ pub struct Ident { impl Ident { #[inline] /// Constructs a new identifier from a symbol and a span. - pub const fn new(name: Symbol, span: Span) -> Ident { + pub fn new(name: Symbol, span: Span) -> Ident { + assert_ne!(name, kw::Empty); Ident { name, span } } /// Constructs a new identifier with a dummy span. #[inline] - pub const fn with_dummy_span(name: Symbol) -> Ident { + pub fn with_dummy_span(name: Symbol) -> Ident { Ident::new(name, DUMMY_SP) } - /// This is best avoided, because it blurs the lines between "empty - /// identifier" and "no identifier". Using `Option` is preferable, - /// where possible, because that is unambiguous. - #[inline] - pub fn empty() -> Ident { - Ident::with_dummy_span(kw::Empty) - } - // For dummy identifiers that are never used and absolutely must be - // present, it's better to use `Ident::dummy` than `Ident::Empty`, because - // it's clearer that it's intended as a dummy value, and more likely to be - // detected if it accidentally does get used. + // present. Note that this does *not* use the empty symbol; `sym::dummy` + // makes it clear that it's intended as a dummy value, and is more likely + // to be detected if it accidentally does get used. #[inline] pub fn dummy() -> Ident { Ident::with_dummy_span(sym::dummy) diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index e967fd406093..d684e6f8650f 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -167,7 +167,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { } fn usually_needs_space_between_keyword_and_open_delim(symbol: Symbol, span: Span) -> bool { - let ident = Ident { name: symbol, span }; + let ident = Ident::new(symbol, span); let is_keyword = ident.is_used_keyword() || ident.is_unused_keyword(); if !is_keyword { // An identifier that is not a keyword usually does not need a space diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 36f5889dcf4e..f3e2138d1a57 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -496,12 +496,21 @@ impl<'tcx> LinkCollector<'_, 'tcx> { // Try looking for methods and associated items. // NB: `path_root` could be empty when resolving in the root namespace (e.g. `::std`). - let (path_root, item_str) = path_str.rsplit_once("::").ok_or_else(|| { - // If there's no `::`, it's not an associated item. - // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved. - debug!("found no `::`, assuming {path_str} was correctly not in scope"); - UnresolvedPath { item_id, module_id, partial_res: None, unresolved: path_str.into() } - })?; + let (path_root, item_str) = match path_str.rsplit_once("::") { + Some(res @ (_path_root, item_str)) if !item_str.is_empty() => res, + _ => { + // If there's no `::`, or the `::` is at the end (e.g. `String::`) it's not an + // associated item. So we can be sure that `rustc_resolve` was accurate when it + // said it wasn't resolved. + debug!("`::` missing or at end, assuming {path_str} was not in scope"); + return Err(UnresolvedPath { + item_id, + module_id, + partial_res: None, + unresolved: path_str.into(), + }); + } + }; let item_name = Symbol::intern(item_str); // FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support From 767d64da45cef73a2241630da9ddfbc29bd525be Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 9 May 2025 11:13:08 +0200 Subject: [PATCH 260/262] bump version number to 1.89.0 --- src/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version b/src/version index 59be592144c2..636ea711ad96 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.88.0 +1.89.0 From 7dae31828baaeb26f913dcad6c83bbed5a8700b4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 20 Nov 2024 20:29:01 +0800 Subject: [PATCH 261/262] Disarm `time` bomb (diagnostics) Revert "Rollup merge of #129343 - estebank:time-version, r=jieyouxu" This reverts commit 26f75a65d70773e4520634b9f6599ddf08c499e6, reversing changes made to 2572e0e8c9d5d671eccb1d5791e55c929c4720f4. Imports are modified to fix merge conflicts and remove unused ones. --- compiler/rustc_span/src/symbol.rs | 1 - compiler/rustc_trait_selection/messages.ftl | 2 - .../error_reporting/infer/need_type_info.rs | 46 +------------------ compiler/rustc_trait_selection/src/errors.rs | 2 - ...d-time-version-format_description-parse.rs | 13 ------ ...me-version-format_description-parse.stderr | 14 ------ 6 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 tests/ui/inference/detect-old-time-version-format_description-parse.rs delete mode 100644 tests/ui/inference/detect-old-time-version-format_description-parse.stderr diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f2f6d1a3bcf8..b6cb6113f9fc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2099,7 +2099,6 @@ symbols! { three_way_compare, thumb2, thumb_mode: "thumb-mode", - time, tmm_reg, to_owned_method, to_string, diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index cf6dd40718b3..00922c6038ee 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -452,8 +452,6 @@ trait_selection_type_annotations_needed = {$source_kind -> } .label = type must be known at this point -trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update` - trait_selection_types_declared_different = these two types are declared with different lifetimes... trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated} diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index de9a50f19623..cb1c9c753690 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -6,7 +6,7 @@ use rustc_errors::codes::*; use rustc_errors::{Diag, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; use rustc_middle::bug; @@ -17,7 +17,7 @@ use rustc_middle::ty::{ self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypeckResults, }; -use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, Span, sym}; use tracing::{debug, instrument, warn}; use super::nice_region_error::placeholder_error::Highlighted; @@ -438,7 +438,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { bad_label, was_written: false, path: Default::default(), - time_version: false, }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -630,10 +629,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } } - - let time_version = - self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags); - match error_code { TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired { span, @@ -645,7 +640,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { bad_label: None, was_written: path.is_some(), path: path.unwrap_or_default(), - time_version, }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -671,42 +665,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }), } } - - /// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error. - /// - // FIXME: we should figure out a more generic version of doing this, ideally in cargo itself. - fn detect_old_time_crate_version( - &self, - span: Option, - kind: &InferSourceKind<'_>, - // We will clear the non-actionable suggestion from the error to reduce noise. - infer_subdiags: &mut Vec>, - ) -> bool { - // FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing - // compilation once we promote 1.89 to beta, which will happen in 9 months from now. - #[cfg(not(version("1.89")))] - const fn version_check() {} - #[cfg(version("1.89"))] - const fn version_check() { - panic!("remove this check as presumably the ecosystem has moved from needing it"); - } - const { version_check() }; - // Only relevant when building the `time` crate. - if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time - && let Some(span) = span - && let InferSourceKind::LetBinding { pattern_name, .. } = kind - && let Some(name) = pattern_name - && name.as_str() == "items" - && let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span) - { - let path = file.local_path_if_available().to_string_lossy(); - if path.contains("format_description") && path.contains("parse") { - infer_subdiags.clear(); - return true; - } - } - false - } } #[derive(Debug)] diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 04cae1c9b641..8ab4d795c459 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -219,8 +219,6 @@ pub struct AnnotationRequired<'a> { #[note(trait_selection_full_type_written)] pub was_written: bool, pub path: PathBuf, - #[note(trait_selection_type_annotations_needed_error_time)] - pub time_version: bool, } // Copy of `AnnotationRequired` for E0283 diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.rs b/tests/ui/inference/detect-old-time-version-format_description-parse.rs deleted file mode 100644 index 386b2a3bf3c8..000000000000 --- a/tests/ui/inference/detect-old-time-version-format_description-parse.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![crate_name = "time"] -#![crate_type = "lib"] - -// This code compiled without error in Rust 1.79, but started failing in 1.80 -// after the addition of several `impl FromIterator<_> for Box`. - -pub fn parse() -> Option> { - let iter = std::iter::once(Some(())).map(|o| o.map(Into::into)); - let items = iter.collect::>>()?; //~ ERROR E0282 - //~^ NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` - Some(items.into()) - //~^ NOTE type must be known at this point -} diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr deleted file mode 100644 index a70ce9dd2681..000000000000 --- a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed for `Box<_>` - --> $DIR/detect-old-time-version-format_description-parse.rs:9:9 - | -LL | let items = iter.collect::>>()?; - | ^^^^^ -LL | -LL | Some(items.into()) - | ---- type must be known at this point - | - = note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. From 35679bad981e1551138a8b367c0571b0a5928a27 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 9 May 2025 09:36:33 -0700 Subject: [PATCH 262/262] Enable non-leaf Frame Pointers for Arm64EC Windows --- .../src/spec/targets/arm64ec_pc_windows_msvc.rs | 8 +++++++- tests/assembly/asm/aarch64-types.rs | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index bb3e3e544cba..8f93523909e3 100644 --- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base}; +use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -10,6 +10,12 @@ pub(crate) fn target() -> Target { &["/machine:arm64ec", "softintrin.lib"], ); + // Microsoft recommends enabling frame pointers on Arm64 Windows. + // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers + // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW + // and other services. It must point to the previous {x29, x30} pair on the stack." + base.frame_pointer = FramePointer::NonLeaf; + Target { llvm_target: "arm64ec-pc-windows-msvc".into(), metadata: TargetMetadata { diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs index 8e4e08503253..ad2770d43e37 100644 --- a/tests/assembly/asm/aarch64-types.rs +++ b/tests/assembly/asm/aarch64-types.rs @@ -86,10 +86,12 @@ pub unsafe fn sym_static() { // Regression test for #75761 // CHECK-LABEL: {{("#)?}}issue_75761{{"?}} -// CHECK: str {{.*}}x30 +// aarch64: str {{.*}}x30 +// arm64ec: stp {{.*}}x30 // CHECK: //APP // CHECK: //NO_APP -// CHECK: ldr {{.*}}x30 +// aarch64: ldr {{.*}}x30 +// arm64ec: ldp {{.*}}x30 #[no_mangle] pub unsafe fn issue_75761() { asm!("", out("v0") _, out("x30") _);