From 88d314ad4cdebe248170d2fd7fe28580c02acecb Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Sat, 6 Jun 2026 23:01:26 -0700 Subject: [PATCH 1/9] typeck enum discrs before attempting to compute layout --- compiler/rustc_ty_utils/src/layout.rs | 12 +++++++ tests/crashes/138660.rs | 7 ---- ...on-int-discriminant-promoted-ice-138660.rs | 13 ++++++++ ...nt-discriminant-promoted-ice-138660.stderr | 33 +++++++++++++++++++ .../size-of-discriminant-no-cycle.rs | 8 +++++ 5 files changed, 66 insertions(+), 7 deletions(-) delete mode 100644 tests/crashes/138660.rs create mode 100644 tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs create mode 100644 tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr create mode 100644 tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index ee6afdf330a77..81d3185fea01a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -707,6 +707,18 @@ fn layout_of_uncached<'tcx>( let discr_range_of_repr = |min, max| abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min, max); + // We shouldn't be computing the layout of discrs that fail typeck + if def.is_enum() { + for v in def.variants() { + if let ty::VariantDiscr::Explicit(def_id) = v.discr + && let Some(local_did) = def_id.as_local() + && let Some(guar) = tcx.typeck(local_did).tainted_by_errors + { + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + } + } + let discriminants_iter = || { def.is_enum() .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128))) diff --git a/tests/crashes/138660.rs b/tests/crashes/138660.rs deleted file mode 100644 index 90eb8026f072f..0000000000000 --- a/tests/crashes/138660.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #138660 -enum A { - V1(isize) = 1..=10, - V0 = 1..=10, -} -const B: &'static [A] = &[A::V0, A::V1(111)]; -fn main() {} diff --git a/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs new file mode 100644 index 0000000000000..c1e968494540c --- /dev/null +++ b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs @@ -0,0 +1,13 @@ +// Previously, enums with non-int discrs ICEd during CTFE of promoteds. + +enum A { +//~^ ERROR `#[repr(inttype)]` must be specified + V1(isize) = 1..=10, + //~^ ERROR mismatched types + V0 = 1..=10, + //~^ ERROR mismatched types +} + +const B: &'static [A] = &[A::V0, A::V1(111)]; + +fn main() {} diff --git a/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr new file mode 100644 index 0000000000000..19491ce733d09 --- /dev/null +++ b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:5:17 + | +LL | V1(isize) = 1..=10, + | ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>` + | + = note: expected type `isize` + found struct `std::ops::RangeInclusive<{integer}>` + = note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr` + +error[E0308]: mismatched types + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:7:10 + | +LL | V0 = 1..=10, + | ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>` + | + = note: expected type `isize` + found struct `std::ops::RangeInclusive<{integer}>` + = note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr` + +error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:3:1 + | +LL | enum A { + | ^^^^^^ +LL | +LL | V1(isize) = 1..=10, + | ------ explicit discriminant on non-unit variant specified here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0732. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs b/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs new file mode 100644 index 0000000000000..09313735fd4c5 --- /dev/null +++ b/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs @@ -0,0 +1,8 @@ +//@ check-pass +// Ensure that `size_of::()` as a discriminant does not cause a cycle error. + +enum Thing { + Variant = size_of::() as isize, +} + +fn main() {} From dddede5a8b0d0973da41559d0e818f2f48337201 Mon Sep 17 00:00:00 2001 From: zakrad <49591476+zakrad@users.noreply.github.com> Date: Mon, 21 Sep 2026 14:30:40 +0330 Subject: [PATCH 2/9] Add regression test for hang on mutually recursive trait impls --- ...recursive-impls-hang-143018.current.stderr | 9 ++++++ ...ly-recursive-impls-hang-143018.next.stderr | 15 ++++++++++ .../mutually-recursive-impls-hang-143018.rs | 29 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr create mode 100644 tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr create mode 100644 tests/ui/traits/mutually-recursive-impls-hang-143018.rs diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr b/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr new file mode 100644 index 0000000000000..c6410d7eac39c --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/mutually-recursive-impls-hang-143018.rs:26:5 + | +LL | impls_trait::(); + | ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr b/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr new file mode 100644 index 0000000000000..680182b7350c8 --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `A: Trait<_>` + --> $DIR/mutually-recursive-impls-hang-143018.rs:26:19 + | +LL | impls_trait::(); + | ^ + | +note: required by a bound in `impls_trait` + --> $DIR/mutually-recursive-impls-hang-143018.rs:24:19 + | +LL | fn impls_trait, V>() {} + | ^^^^^^^^ required by this bound in `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.rs b/tests/ui/traits/mutually-recursive-impls-hang-143018.rs new file mode 100644 index 0000000000000..8db92502a8621 --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.rs @@ -0,0 +1,29 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . + +trait Trait {} +struct A; +struct B; + +impl Trait for A +where + A: Trait, + B: Trait, +{ +} + +impl Trait for B +where + A: Trait, +{ +} + +fn impls_trait, V>() {} +fn main() { + impls_trait::(); + //[current]~^ ERROR type annotations needed + //[next]~^^ ERROR overflow evaluating the requirement +} From 3285cce3dad8e74b1ecaf98675cc8b218c900758 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 19 Sep 2026 16:30:33 +0200 Subject: [PATCH 3/9] fix `va_arg` on `f128` on `x86` --- compiler/rustc_codegen_llvm/src/va_arg.rs | 31 +++++++---- tests/assembly-llvm/c-variadic/x86-linux.rs | 57 +++++++++++++++++---- 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index b21ce3f2be8e4..18229e6d14ba5 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1057,15 +1057,28 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( let stability = target.supports_c_variadic_definitions(); match target.arch { - Arch::X86 => emit_ptr_va_arg( - bx, - addr, - layout, - PassMode::Direct, - SlotSize::Bytes4, - if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, - ForceRightAdjust::No, - ), + Arch::X86 => { + // A small deviation from clang to get the right behavior for f128. + // + // Note that i64 and f64 have an alignment of only 4 on this architecture. + // We need to be careful when adding future types with an alignment bigger + // than 4 (e.g. i128), clang has a bunch of custom logic for them. + let allow_higher_align = if layout.ty == bx.tcx().types.f128 { + AllowHigherAlign::Yes + } else { + AllowHigherAlign::No + }; + + emit_ptr_va_arg( + bx, + addr, + layout, + PassMode::Direct, + SlotSize::Bytes4, + allow_higher_align, + ForceRightAdjust::No, + ) + } Arch::Arm64EC => emit_ptr_va_arg( bx, addr, diff --git a/tests/assembly-llvm/c-variadic/x86-linux.rs b/tests/assembly-llvm/c-variadic/x86-linux.rs index d2f5c1144a991..de647ca861cb6 100644 --- a/tests/assembly-llvm/c-variadic/x86-linux.rs +++ b/tests/assembly-llvm/c-variadic/x86-linux.rs @@ -9,7 +9,7 @@ //@ [I686] compile-flags: -Copt-level=3 -Cllvm-args=-x86-asm-syntax=intel //@ [I686] compile-flags: --target i686-unknown-linux-gnu //@ needs-llvm-components: x86 -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, f128)] #![no_core] #![crate_type = "lib"] @@ -64,20 +64,55 @@ unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { ap.next_arg() } +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f128(ap: &mut VaList<'_>) -> f128 { + // CHECK-LABEL: read_f128 + + // X86_64: mov ecx, dword ptr [rdi + 4] + // X86_64-NEXT: cmp rcx, 160 + // X86_64-NEXT: ja .LBB1_2 + // X86_64-NEXT: mov rax, rcx + // X86_64-NEXT: add rax, qword ptr [rdi + 16] + // X86_64-NEXT: add ecx, 16 + // X86_64-NEXT: mov dword ptr [rdi + 4], ecx + // X86_64-NEXT: movaps xmm0, xmmword ptr [rax] + // X86_64-NEXT: ret + // X86_64-NEXT: .LBB1_2: + // X86_64-NEXT: mov rax, qword ptr [rdi + 8] + // X86_64-NEXT: add rax, 15 + // X86_64-NEXT: and rax, -16 + // X86_64-NEXT: lea rcx, [rax + 16] + // X86_64-NEXT: mov qword ptr [rdi + 8], rcx + // X86_64-NEXT: movaps xmm0, xmmword ptr [rax] + // X86_64-NEXT: ret + + // I686: mov ecx, dword ptr [esp + 12] + // I686-NEXT: mov eax, dword ptr [esp + 8] + // I686-NEXT: mov edx, dword ptr [ecx] + // I686-NEXT: add edx, 15 + // I686-NEXT: and edx, -16 + // I686-NEXT: lea esi, [edx + 16] + // I686-NEXT: mov dword ptr [ecx], esi + // I686-NEXT: movaps xmm0, xmmword ptr [edx] + // I686-NEXT: movaps xmmword ptr [eax], xmm0 + // I686-NEXT: pop esi + ap.next_arg() +} + #[unsafe(no_mangle)] unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // CHECK-LABEL: read_i32 // // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 40 - // X86_64-NEXT: ja .LBB1_2 + // X86_64-NEXT: ja .LBB2_2 // X86_64-NEXT: mov rax, rcx // X86_64-NEXT: add rax, qword ptr [rdi + 16] // X86_64-NEXT: add ecx, 8 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: mov eax, dword ptr [rax] // X86_64-NEXT: ret - // X86_64-NEXT: .LBB1_2: + // X86_64-NEXT: .LBB2_2: // X86_64-NEXT: mov rax, qword ptr [rdi + 8] // X86_64-NEXT: lea rcx, [rax + 8] // X86_64-NEXT: mov qword ptr [rdi + 8], rcx @@ -86,14 +121,14 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 40 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB1_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB2_2 // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: add eax, ecx // X86_64-NEXT_GNUX32-NEXT: add ecx, 8 // X86_64-NEXT_GNUX32-NEXT: mov dword ptr [edi], ecx // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [eax] // X86_64-NEXT_GNUX32-NEXT: ret - // X86_64-NEXT_GNUX32-NEXT: .LBB1_2: + // X86_64-NEXT_GNUX32-NEXT: .LBB2_2: // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 8] // X86_64-NEXT_GNUX32-NEXT: lea ecx, [rax + 8] // X86_64-NEXT_GNUX32-NEXT: mov dword ptr [edi + 8], ecx @@ -115,14 +150,14 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 40 - // X86_64-NEXT: ja .LBB2_2 + // X86_64-NEXT: ja .LBB3_2 // X86_64-NEXT: mov rax, rcx // X86_64-NEXT: add rax, qword ptr [rdi + 16] // X86_64-NEXT: add ecx, 8 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: mov rax, qword ptr [rax] // X86_64-NEXT: ret - // X86_64-NEXT: .LBB2_2: + // X86_64-NEXT: .LBB3_2: // X86_64-NEXT: mov rax, qword ptr [rdi + 8] // X86_64-NEXT: lea rcx, [rax + 8] // X86_64-NEXT: mov qword ptr [rdi + 8], rcx @@ -131,7 +166,7 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 40 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB2_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB3_2 // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: add eax, ecx // X86_64-NEXT_GNUX32-NEXT: add ecx, 8 @@ -162,14 +197,14 @@ unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { // // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 32 - // X86_64-NEXT: ja .LBB3_2 + // X86_64-NEXT: ja .LBB4_2 // X86_64-NEXT: mov rdx, qword ptr [rdi + 16] // X86_64-NEXT: mov rax, qword ptr [rdx + rcx] // X86_64-NEXT: mov rdx, qword ptr [rdx + rcx + 8] // X86_64-NEXT: add ecx, 16 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: ret - // X86_64-NEXT: .LBB3_2: + // X86_64-NEXT: .LBB4_2: // X86_64-NEXT: mov rcx, qword ptr [rdi + 8] // X86_64-NEXT: add rcx, 15 // X86_64-NEXT: and rcx, -16 @@ -181,7 +216,7 @@ unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 32 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB3_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB4_2 // X86_64-NEXT_GNUX32-NEXT: mov edx, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: mov rax, qword ptr [edx + ecx] // X86_64-NEXT_GNUX32-NEXT: mov rdx, qword ptr [edx + ecx + 8] From caadd686be32b2116709820c231ca09bc66ceac5 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Fri, 4 Sep 2026 11:37:27 +0800 Subject: [PATCH 4/9] dont lower depth for coroutine witness and rigid opaques in auto trait proving --- .../src/solve/eval_ctxt/mod.rs | 130 +++++++++++++++--- .../src/solve/project_goals/mod.rs | 12 +- ...ower-depth-for-witness-and-rigid-opaque.rs | 31 +++++ 3 files changed, 145 insertions(+), 28 deletions(-) create mode 100644 tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs 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 ae5cf61aac91e..823e606eea0a0 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 @@ -636,12 +636,119 @@ where source: GoalSource, goal: Goal, ) -> Result, NoSolutionOrRerunNonErased> { - let (normalization_nested_goals, goal_evaluation) = - self.evaluate_goal_raw(source, goal, LowerAvailableDepth::Yes)?; + let (normalization_nested_goals, goal_evaluation) = self.evaluate_goal_raw(source, goal)?; assert!(normalization_nested_goals.is_empty()); Ok(goal_evaluation) } + fn evaluate_in_search_graph( + &mut self, + canonical_goal: I::CanonicalInput, + step_kind: PathKind, + ) -> (Result, NoSolution>, AccessedOpaques) { + let increase_depth_for_nested = + match canonical_goal.canonical.value.goal.predicate.kind().skip_binder() { + // We don't lower the available depth for the `NormalizesTo` goal, as evaluating + // it is an extra step only exists in the new solver that behaves like a function + // call rather than an independent nested goal evaluation. So, decreasing the + // available depth may end up regressions which hit the recursion limits for crates + // compiled well with the old solver. + ty::PredicateKind::NormalizesTo(_) => LowerAvailableDepth::No, + // We also don't lower depth for witness and rigid opaque when proving auto traits. + // This is to mitigate the overflow FCW warnings in deeply nested async calls. + // See #159228. + // + // We're eventually going to remove the witness type so it's okay to ignore the + // depth. + // For rigid opaques, revealing hidden types can be viewed as normalization so it's + // consistent with the `NormalizesTo` reasoning above. + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + if self.cx().trait_is_auto(pred.trait_ref.def_id) { + match pred.self_ty().kind() { + ty::CoroutineWitness(..) => LowerAvailableDepth::No, + ty::Alias( + ty::IsRigid::Yes, + ty::AliasTy { kind: ty::Opaque { def_id, .. }, .. }, + ) => { + // We only want to skip lowering depth when the proving is done via + // auto trait leakage. If the goal can be proved via item bounds, + // we should lower depth faithfully. + // + // FIXME: We can have param env candidates via TAIT or RTN. + // Ideally we'd instead lower the depth for the nested goal instead. + // Implementing this is a bit harder. + if self + .cx() + .item_self_bounds(def_id.into()) + .skip_binder() + .into_iter() + .any(|bound| { + bound + .as_trait_clause() + .is_some_and(|b| b.def_id() == pred.def_id()) + }) + { + LowerAvailableDepth::Yes + } else { + LowerAvailableDepth::No + } + } + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::Pat(..) + | ty::FnPtr(..) + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Never + | ty::Tuple(..) + | ty::UnsafeBinder(_) + | ty::Param(..) + | ty::Placeholder(..) + | ty::Bound(..) + | ty::Infer(..) + | ty::Alias(_, _) + | ty::Ref(_, _, _) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Dynamic(..) + | ty::Error(_) + | ty::FnDef(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) => LowerAvailableDepth::Yes, + } + } else { + LowerAvailableDepth::Yes + } + } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(_, _)) + | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) + | ty::PredicateKind::Subtype(_) + | ty::PredicateKind::Coerce(_) + | ty::PredicateKind::DynCompatible(_) + | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) + | ty::PredicateKind::ConstEquate(_, _) + | ty::PredicateKind::Ambiguous => LowerAvailableDepth::Yes, + }; + self.search_graph.evaluate_goal( + self.cx(), + canonical_goal, + step_kind, + increase_depth_for_nested, + &mut inspect::ProofTreeBuilder::new_noop(), + ) + } + /// Recursively evaluates `goal`, returning the nested goals in case /// the nested goal is a `NormalizesTo` goal. /// @@ -653,7 +760,6 @@ where &mut self, source: GoalSource, goal: Goal, - increase_depth_for_nested: LowerAvailableDepth, ) -> Result<(NestedNormalizationGoals, GoalEvaluation), NoSolutionOrRerunNonErased> { // We only care about one entry per `OpaqueTypeKey` here, // so we only canonicalize the lookup table and ignore @@ -719,13 +825,8 @@ where TypingMode::ErasedNotCoherence(MayBeErased), ); - let (canonical_result, accessed_opaques) = self.search_graph.evaluate_goal( - self.cx(), - canonical_goal, - step_kind, - increase_depth_for_nested, - &mut inspect::ProofTreeBuilder::new_noop(), - ); + let (canonical_result, accessed_opaques) = + self.evaluate_in_search_graph(canonical_goal, step_kind); let should_rerun = should_rerun_after_erased_canonicalization( accessed_opaques, @@ -759,13 +860,8 @@ where let (orig_values, canonical_goal) = canonicalize_goal(self.delegate, goal, &opaque_types, typing_mode); - let (canonical_result, accessed_opaques) = self.search_graph.evaluate_goal( - self.cx(), - canonical_goal, - step_kind, - increase_depth_for_nested, - &mut inspect::ProofTreeBuilder::new_noop(), - ); + let (canonical_result, accessed_opaques) = + self.evaluate_in_search_graph(canonical_goal, step_kind); assert!( !accessed_opaques.might_rerun(), "we run without TypingMode::ErasedNotCoherence, so opaques are available, and we don't retry if the outer typing mode is ErasedNotCoherence: {accessed_opaques:?} after {goal:?}" diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs index db326e6d736a4..9d6b8875071ba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs @@ -3,7 +3,6 @@ mod free_alias; mod inherent; mod opaque_types; -use rustc_type_ir::search_graph::LowerAvailableDepth; use rustc_type_ir::solve::QueryResultOrRerunNonErased; use rustc_type_ir::{self as ty, Interner, ProjectionClause}; use tracing::{instrument, trace}; @@ -70,16 +69,7 @@ where let ( NestedNormalizationGoals(nested_goals), GoalEvaluation { goal: _, certainty, stalled_on: _, has_changed: _ }, - ) = self.evaluate_goal_raw( - GoalSource::TypeRelating, - normalizes_to, - // We don't lower thr available depth for this `NormalizesTo` goal, as evaluating - // it is an extra step only exists in the new solver that behaves like a function - // call rather than an independent nested goal evaluation. So, decreasing the - // available depth may end up regressions which hit the recursion limits for crates - // compiled well with the old solver. - LowerAvailableDepth::No, - )?; + ) = self.evaluate_goal_raw(GoalSource::TypeRelating, normalizes_to)?; trace!(?nested_goals); diff --git a/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs b/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs new file mode 100644 index 0000000000000..c4d493ec0f8d2 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -Znext-solver +//@ edition: 2024 +//@ check-pass + +// We don't increase recursion depth when proving auto traits for witness +// and rigid opaques. This is to mitigate the FCW warnings in deeply nested +// async calls. See #159228. + +#![recursion_limit = "6"] + +async fn foo1() {} + +async fn foo2() { + foo1().await +} +async fn foo3() { + foo2().await +} +async fn foo4() { + foo3().await +} + +async fn foo5() { + foo4().await +} + +fn assert_send(_: T) {} + +fn main() { + assert_send(foo5()); +} From ec51dae63f95027d6acb731b759de05698892551 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Apr 2026 14:13:43 +0200 Subject: [PATCH 5/9] Check the entire library and cg_clif workspaces for permitted deps in tidy We ship the entire library workspace in the rust-src component, so even if the standard library doesn't depend on a crate, having it in the library workspace still increases the amount of storage a rust install takes. And for cg_clif I personally want to keep deps to a minimum even those not for the backend itself. --- src/tools/tidy/src/deps.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 65a7890a5ecc2..2c3a47228ac3f 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -96,10 +96,11 @@ pub(crate) struct WorkspaceInfo<'a> { /// The list of license exceptions. pub(crate) exceptions: ExceptionList, /// Optionally: - /// * A list of crates for which dependencies need to be explicitly allowed. + /// * A list of crates for which dependencies need to be explicitly allowed + /// or None to check the entire workspace. /// * The list of allowed dependencies. /// * The source code location of the allowed dependencies list - crates_and_deps: Option<(&'a [&'a str], &'a [&'a str], ListLocation)>, + crates_and_deps: Option<(Option<&'a [&'a str]>, &'a [&'a str], ListLocation)>, /// Submodules required for the workspace pub(crate) submodules: &'a [&'a str], } @@ -114,7 +115,7 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ path: ".", exceptions: EXCEPTIONS, crates_and_deps: Some(( - &["rustc-main"], + Some(&["rustc-main"]), PERMITTED_RUSTC_DEPENDENCIES, PERMITTED_RUSTC_DEPS_LOCATION, )), @@ -124,7 +125,7 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ path: "library", exceptions: EXCEPTIONS_STDLIB, crates_and_deps: Some(( - &["sysroot"], + None, PERMITTED_STDLIB_DEPENDENCIES, PERMITTED_STDLIB_DEPS_LOCATION, )), @@ -140,7 +141,7 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ path: "compiler/rustc_codegen_cranelift", exceptions: EXCEPTIONS_CRANELIFT, crates_and_deps: Some(( - &["rustc_codegen_cranelift"], + None, PERMITTED_CRANELIFT_DEPENDENCIES, PERMITTED_CRANELIFT_DEPS_LOCATION, )), @@ -664,7 +665,7 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { } check_license_exceptions(&metadata, path, exceptions, &mut check); if let Some((crates, permitted_deps, location)) = crates_and_deps { - let descr = crates.get(0).unwrap_or(&path); + let descr = crates.map_or(path, |crates| crates.get(0).unwrap_or(&path)); check_permitted_dependencies( &metadata, descr, @@ -927,15 +928,21 @@ fn check_permitted_dependencies( metadata: &Metadata, descr: &str, permitted_dependencies: &[&'static str], - restricted_dependency_crates: &[&'static str], + restricted_dependency_crates: Option<&[&'static str]>, permitted_location: ListLocation, check: &mut RunningCheck, ) { let mut has_permitted_dep_error = false; let mut deps = HashSet::new(); - for to_check in restricted_dependency_crates { - let to_check = pkg_from_name(metadata, to_check); - deps_of(metadata, &to_check.id, &mut deps); + if let Some(restricted_dependency_crates) = restricted_dependency_crates { + for to_check in restricted_dependency_crates { + let to_check = pkg_from_name(metadata, to_check); + deps_of(metadata, &to_check.id, &mut deps); + } + } else { + for to_check in &metadata.packages { + deps_of(metadata, &to_check.id, &mut deps); + } } // Check that the PERMITTED_DEPENDENCIES does not have unused entries. From 96b181cdac89beb9ae230078007d4789dd68712e Mon Sep 17 00:00:00 2001 From: Jakub Chlanda Date: Thu, 3 Sep 2026 10:11:56 +0000 Subject: [PATCH 6/9] tests: Run more pauth tests in CI and make them pass Some pauth tests have ended up failing since they were not run in CI. Make them run and make them pass. --- tests/assembly-llvm/pauth-basic.rs | 2 +- tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs | 1 - tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs | 2 ++ .../pauth/pauth-extern-c-direct-indirect-call.rs | 4 +++- tests/codegen-llvm/pauth/pauth-extern-c.rs | 1 - tests/codegen-llvm/pauth/pauth-extern-weak-global.rs | 1 - tests/codegen-llvm/pauth/pauth-init-fini.rs | 1 - tests/ui/statics/crt-static-pauthtest.rs | 3 +-- tests/ui/target_modifiers/auxiliary/pauth.rs | 3 ++- .../incompatible_pauth.error_generated.stderr | 4 ---- tests/ui/target_modifiers/incompatible_pauth.rs | 6 +++--- 11 files changed, 12 insertions(+), 16 deletions(-) diff --git a/tests/assembly-llvm/pauth-basic.rs b/tests/assembly-llvm/pauth-basic.rs index e240e1317f3a3..34b9c4b5c328c 100644 --- a/tests/assembly-llvm/pauth-basic.rs +++ b/tests/assembly-llvm/pauth-basic.rs @@ -1,8 +1,8 @@ //@ add-minicore //@ assembly-output: emit-asm -//@ only-pauthtest //@ revisions: aarch64_unknown_linux_pauthtest //@ [aarch64_unknown_linux_pauthtest] compile-flags: --target=aarch64-unknown-linux-pauthtest +//@ [aarch64_unknown_linux_pauthtest] compile-flags: -Copt-level=3 //@ [aarch64_unknown_linux_pauthtest] needs-llvm-components: aarch64 #![feature(no_core, lang_items)] diff --git a/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs b/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs index 04af1b66140dd..513850f1dd4db 100644 --- a/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs +++ b/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs @@ -1,5 +1,4 @@ // ignore-tidy-file-linelength -//@ only-pauthtest //@ revisions: DEFAULT ALL DISABLE_JUMP DISABLE_AUTH_TRAPS DISABLE_CALLS DISABLE_INDIRCT_GOTOS DISABLE_RETURNS DISABLE_INTRINSICS DISABLE_TYPEINFO DISABLE_VT_PTR_ADDR DISABLE_VT_PTR_TYPE NONE //@ add-minicore diff --git a/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs b/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs index 2751494b9de7a..24ab1abb10e67 100644 --- a/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs +++ b/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs @@ -3,6 +3,8 @@ // Make sure that compiler generated functions (main wrapper and __rust_try) also have ptrauth // attributes set correctly. Rustc only generates __rust_try at O0, so use that opt level for the // test. +// Cannot be converted to minicore: catch_unwind is a std API and is what causes rustc to generate +// the __rust_try wrapper this test is checking. //@ needs-llvm-components: aarch64 diff --git a/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs b/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs index 643b428339b73..d01815954b237 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs @@ -1,10 +1,12 @@ //@ add-minicore // ignore-tidy-linelength -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH //@ [O0_PAUTH] needs-llvm-components: aarch64 //@ [O0_PAUTH] compile-flags: --target=aarch64-unknown-linux-pauthtest -C opt-level=0 +// O3_PAUTH relies on an InstCombine fold that removes the redundant `ptrauth` bundle from calls. +// That fold first shipped in LLVM 22, gate this revision accordingly. +//@ [O3_PAUTH] min-llvm-version: 22 //@ [O3_PAUTH] needs-llvm-components: aarch64 //@ [O3_PAUTH] compile-flags: --target=aarch64-unknown-linux-pauthtest -C opt-level=3 diff --git a/tests/codegen-llvm/pauth/pauth-extern-c.rs b/tests/codegen-llvm/pauth/pauth-extern-c.rs index b22cf6943a804..07e27965e9ebf 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-c.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-c.rs @@ -1,5 +1,4 @@ // ignore-tidy-file-linelength -//@ only-pauthtest //@ add-minicore //@ revisions: O0_PAUTH O3_PAUTH O0_PAUTH-ELF-GOT O3_PAUTH-ELF-GOT O0_NO_PAUTH O3_NO_PAUTH diff --git a/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs b/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs index a83298dd5725c..b7c1f5fd06479 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs @@ -1,5 +1,4 @@ // ignore-tidy-linelength -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH O0_NO_PAUTH O3_NO_PAUTH //@ add-minicore diff --git a/tests/codegen-llvm/pauth/pauth-init-fini.rs b/tests/codegen-llvm/pauth/pauth-init-fini.rs index b54006e56f1f4..5550100ae7f92 100644 --- a/tests/codegen-llvm/pauth/pauth-init-fini.rs +++ b/tests/codegen-llvm/pauth/pauth-init-fini.rs @@ -1,6 +1,5 @@ // ignore-tidy-file-linelength //@ add-minicore -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH O0_PAUTH-ADDR-DISC O3_PAUTH-ADDR-DISC O0_PAUTH-NO-INIT-FINI O3_PAUTH-NO-INIT-FINI //@ [O0_PAUTH] needs-llvm-components: aarch64 diff --git a/tests/ui/statics/crt-static-pauthtest.rs b/tests/ui/statics/crt-static-pauthtest.rs index bc5badc600d88..a3fed7f9379ef 100644 --- a/tests/ui/statics/crt-static-pauthtest.rs +++ b/tests/ui/statics/crt-static-pauthtest.rs @@ -1,9 +1,8 @@ //@ compile-flags: -C target-feature=+crt-static --target aarch64-unknown-linux-pauthtest //@ needs-llvm-components: aarch64 -//@ only-pauthtest - #![feature(no_core)] +#![no_core] #![no_main] //~? ERROR pointer authentication requires dynamic linking. Statically linked libc is incompatible, disable it using `-C target-feature=-crt-static` diff --git a/tests/ui/target_modifiers/auxiliary/pauth.rs b/tests/ui/target_modifiers/auxiliary/pauth.rs index 761f4a520a4d2..32bd7651c0b44 100644 --- a/tests/ui/target_modifiers/auxiliary/pauth.rs +++ b/tests/ui/target_modifiers/auxiliary/pauth.rs @@ -1,6 +1,7 @@ //@ compile-flags: --target aarch64-unknown-linux-pauthtest -Zpointer-authentication=+calls,+init-fini //@ needs-llvm-components: aarch64 -//@ only-pauthtest +//@ no-prefer-dynamic +//@ ignore-backends: gcc #![feature(no_core)] #![crate_type = "rlib"] diff --git a/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr b/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr index ddc05e4b55322..1e9390d37e822 100644 --- a/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr +++ b/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr @@ -1,8 +1,4 @@ error: mixing `-Zpointer-authentication` will cause an ABI mismatch in crate `incompatible_pauth` - --> $DIR/incompatible_pauth.rs:14:1 - | -LL | #![feature(no_core)] - | ^ | = help: the `-Zpointer-authentication` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: `-Zpointer-authentication=+calls,-init-fini` in this crate is incompatible with `-Zpointer-authentication=+calls,+init-fini` in dependency `pauth` diff --git a/tests/ui/target_modifiers/incompatible_pauth.rs b/tests/ui/target_modifiers/incompatible_pauth.rs index 6fe77a6916568..302e845e8bd4f 100644 --- a/tests/ui/target_modifiers/incompatible_pauth.rs +++ b/tests/ui/target_modifiers/incompatible_pauth.rs @@ -9,12 +9,12 @@ //@ [ok_reverse_order] check-pass //@ [error_generated] compile-flags: -Zpointer-authentication=+calls,-init-fini //@ needs-llvm-components: aarch64 -//@ only-pauthtest +//@ ignore-backends: gcc #![feature(no_core)] -//[error_generated]~^ ERROR mixing `-Zpointer-authentication` will cause an ABI mismatch in crate -//`incompatible_pauth` #![crate_type = "rlib"] #![no_core] extern crate pauth; + +//[error_generated]~? ERROR mixing `-Zpointer-authentication` will cause an ABI mismatch in crate `incompatible_pauth` From fc538ecc32511eb73230edf12960ca4f8f977be7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:58:46 +0200 Subject: [PATCH 7/9] Add PermittedDeps type --- src/tools/tidy/src/deps.rs | 63 +++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 2c3a47228ac3f..e1a5495f81954 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -95,16 +95,34 @@ pub(crate) struct WorkspaceInfo<'a> { pub(crate) path: &'a str, /// The list of license exceptions. pub(crate) exceptions: ExceptionList, - /// Optionally: - /// * A list of crates for which dependencies need to be explicitly allowed - /// or None to check the entire workspace. - /// * The list of allowed dependencies. - /// * The source code location of the allowed dependencies list - crates_and_deps: Option<(Option<&'a [&'a str]>, &'a [&'a str], ListLocation)>, + /// The list of dependencies that are allowed. If None, any crate with an + /// acceptable license is allowed. + allowed_deps: Option>, /// Submodules required for the workspace pub(crate) submodules: &'a [&'a str], } +#[derive(Clone, Copy)] +struct PermittedDeps<'a> { + /// A list of crates for which dependencies need to be explicitly allowed + /// or None to check the entire workspace. + roots: Option<&'a [&'a str]>, + /// The list of allowed dependencies. + deps: &'a [&'a str], + /// The source code location of the allowed dependencies list. + deps_loc: ListLocation, +} + +impl<'a> PermittedDeps<'a> { + const fn new( + roots: Option<&'a [&'a str]>, + deps: &'a [&'a str], + deps_loc: ListLocation, + ) -> Self { + Self { roots, deps, deps_loc } + } +} + const WORKSPACE_LOCATION: ListLocation = location!(+4); /// The workspaces to check for licensing and optionally permitted dependencies. @@ -114,7 +132,7 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: ".", exceptions: EXCEPTIONS, - crates_and_deps: Some(( + allowed_deps: Some(PermittedDeps::new( Some(&["rustc-main"]), PERMITTED_RUSTC_DEPENDENCIES, PERMITTED_RUSTC_DEPS_LOCATION, @@ -124,7 +142,7 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "library", exceptions: EXCEPTIONS_STDLIB, - crates_and_deps: Some(( + allowed_deps: Some(PermittedDeps::new( None, PERMITTED_STDLIB_DEPENDENCIES, PERMITTED_STDLIB_DEPS_LOCATION, @@ -134,13 +152,13 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "library/stdarch", exceptions: EXCEPTIONS_STDARCH, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "compiler/rustc_codegen_cranelift", exceptions: EXCEPTIONS_CRANELIFT, - crates_and_deps: Some(( + allowed_deps: Some(PermittedDeps::new( None, PERMITTED_CRANELIFT_DEPENDENCIES, PERMITTED_CRANELIFT_DEPS_LOCATION, @@ -150,19 +168,19 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "compiler/rustc_codegen_gcc", exceptions: EXCEPTIONS_GCC, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/bootstrap", exceptions: EXCEPTIONS_BOOTSTRAP, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/tools/cargo", exceptions: EXCEPTIONS_CARGO, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/tools/cargo"], }, // FIXME uncomment once all deps are vendored @@ -179,25 +197,25 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "src/tools/rust-analyzer", exceptions: EXCEPTIONS_RUST_ANALYZER, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/tools/rustbook", exceptions: EXCEPTIONS_RUSTBOOK, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/doc/book", "src/doc/reference"], }, WorkspaceInfo { path: "src/tools/rustc-perf", exceptions: EXCEPTIONS_RUSTC_PERF, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/tools/rustc-perf"], }, WorkspaceInfo { path: "tests/run-make-cargo/uefi-qemu/uefi_qemu_test", exceptions: EXCEPTIONS_UEFI_QEMU_TEST, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, ]; @@ -639,7 +657,8 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { check_proc_macro_dep_list(root, cargo, bless, &mut check); - for &WorkspaceInfo { path, exceptions, crates_and_deps, submodules } in WORKSPACES { + for &WorkspaceInfo { path, exceptions, allowed_deps: crates_and_deps, submodules } in WORKSPACES + { if has_missing_submodule(root, submodules, tidy_ctx.is_running_on_ci()) { continue; } @@ -664,14 +683,14 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { check.error(format!("{path} is part of another workspace ({} != {}), remove from `WORKSPACES` ({WORKSPACE_LOCATION})", absolute_root.display(), absolute_root_real.display())); } check_license_exceptions(&metadata, path, exceptions, &mut check); - if let Some((crates, permitted_deps, location)) = crates_and_deps { - let descr = crates.map_or(path, |crates| crates.get(0).unwrap_or(&path)); + if let Some(PermittedDeps { roots, deps: permitted_deps, deps_loc }) = crates_and_deps { + let descr = roots.map_or(path, |roots| roots.get(0).unwrap_or(&path)); check_permitted_dependencies( &metadata, descr, permitted_deps, - crates, - location, + roots, + deps_loc, &mut check, ); } From 288a941096948e3a6d9e85b7628dcf9b12cab633 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 24 Sep 2026 16:53:39 +0200 Subject: [PATCH 8/9] add jank leak check test --- ...straint-from-nested-projection.next.stderr | 22 +++++++++++++ .../constraint-from-nested-projection.rs | 33 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr create mode 100644 tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs diff --git a/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr new file mode 100644 index 0000000000000..bf3e6943f0d5a --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr @@ -0,0 +1,22 @@ +error[E0283]: type annotations needed + --> $DIR/constraint-from-nested-projection.rs:31:5 + | +LL | pick::<(), _>(); + | ^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `pick` + | +note: multiple `impl`s satisfying `(): Pick<_>` found + --> $DIR/constraint-from-nested-projection.rs:25:1 + | +LL | impl RequiresProject<'a>> Pick for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Pick for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `pick` + --> $DIR/constraint-from-nested-projection.rs:28:12 + | +LL | fn pick, U>() {} + | ^^^^^^^ required by this bound in `pick` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs new file mode 100644 index 0000000000000..fda0fa7efa57c --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs @@ -0,0 +1,33 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@[old] check-pass + +// Evaluate in the old solver does apply constraints from nested `Projection` obligations, +// as they can constrain otherwise unconstrained inference variables. This also allows +// `Projection` goals to otherwise influence its parent obligation by returning constraints +// from matching the impl header. +// +// The new solver entirely ignores region constraints from nested goals in the leak check. +// This is the one case where the the implementation of the new solver will actually weaken +// the leak check. + +trait ProjectStatic<'a> { + type Assoc; +} +impl ProjectStatic<'static> for () { + type Assoc = u32; +} + +trait RequiresProject<'a> {} +impl<'a, T: ProjectStatic<'a, Assoc = u32>> RequiresProject<'a> for T {} + +trait Pick {} +impl RequiresProject<'a>> Pick for T {} +impl Pick for T {} + +fn pick, U>() {} + +fn main() { + pick::<(), _>(); + //[next]~^ ERROR: type annotations needed +} From db4d334408af5e18bc39515b416addf9e263af1b Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Thu, 24 Sep 2026 13:50:10 -0400 Subject: [PATCH 9/9] cleanup: clean up more dependencies that are unused Some were wholly unused, others were unused other than as dev-deps but specified as regular dependencies. This cleans things up a little bit. I used an LLM to smoke out the candidates for this cleanup, but the rest was done by hand. --- Cargo.lock | 1 - src/tools/build-manifest/Cargo.toml | 1 - src/tools/jsondoclint/Cargo.toml | 4 +++- src/tools/remote-test-client/Cargo.toml | 2 +- src/tools/replace-version-placeholder/Cargo.toml | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f35ce252b78e..99c2914ff343d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3440,7 +3440,6 @@ name = "replace-version-placeholder" version = "0.1.0" dependencies = [ "tidy", - "walkdir", ] [[package]] diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 0b766a3e557c5..0900afd6594fe 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -16,5 +16,4 @@ rayon = "1.5.1" hex = "0.4.2" [build-dependencies] -serde = "1" serde_json = "1" diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml index 848c0b37ae94e..e835549878834 100644 --- a/src/tools/jsondoclint/Cargo.toml +++ b/src/tools/jsondoclint/Cargo.toml @@ -9,7 +9,9 @@ edition = "2024" anyhow = "1.0.62" clap = { version = "4.0.15", features = ["derive"] } fs-err = "2.8.1" -rustc-hash = "2.0.0" rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" + +[dev-dependencies] +rustc-hash = "2.0.0" diff --git a/src/tools/remote-test-client/Cargo.toml b/src/tools/remote-test-client/Cargo.toml index 6fe690ba20380..70a6e896a01ab 100644 --- a/src/tools/remote-test-client/Cargo.toml +++ b/src/tools/remote-test-client/Cargo.toml @@ -3,5 +3,5 @@ name = "remote-test-client" version = "0.1.0" edition = "2021" -[dependencies] +[dev-dependencies] assert_cmd = "2" diff --git a/src/tools/replace-version-placeholder/Cargo.toml b/src/tools/replace-version-placeholder/Cargo.toml index 346ce6bd1dbfd..e581194fcf09f 100644 --- a/src/tools/replace-version-placeholder/Cargo.toml +++ b/src/tools/replace-version-placeholder/Cargo.toml @@ -7,4 +7,3 @@ edition = "2021" [dependencies] tidy = { path = "../tidy" } -walkdir = "2"