From c316bdf2930f636ef9c2ef06c42ed6f6d74da5bc Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 29 Jan 2026 18:50:11 +0100 Subject: [PATCH 1/2] don't use env with infer vars --- .../rustc_trait_selection/src/traits/coherence.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index fc628e78a3e23..43a351fd14fba 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -505,15 +505,12 @@ fn impl_intersection_has_negative_obligation( assert_eq!(root_universe, ty::UniverseIndex::ROOT); let impl1_header = fresh_impl_header(infcx, impl1_def_id, is_of_trait); - let param_env = - ty::EarlyBinder::bind(tcx.param_env(impl1_def_id)).instantiate(tcx, impl1_header.impl_args); - let impl2_header = fresh_impl_header(infcx, impl2_def_id, is_of_trait); // Equate the headers to find their intersection (the general type, with infer vars, // that may apply both impls). let Some(equate_obligations) = - equate_impl_headers(infcx, param_env, &impl1_header, &impl2_header) + equate_impl_headers(infcx, ty::ParamEnv::empty(), &impl1_header, &impl2_header) else { return false; }; @@ -531,7 +528,11 @@ fn impl_intersection_has_negative_obligation( root_universe, (impl1_header.impl_args, impl2_header.impl_args), ); - let param_env = infcx.resolve_vars_if_possible(param_env); + + assert!(!impl1_header.impl_args.has_non_region_infer()); + let impl1_header_args = infcx.resolve_vars_if_possible(impl1_header.impl_args); + let param_env = + ty::EarlyBinder::bind(tcx.param_env(impl1_def_id)).instantiate(tcx, impl1_header_args); util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args)) .elaborate_sized() From 642d9c430b339a0998a013abf2081108038241c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 19 Feb 2026 17:21:24 +0100 Subject: [PATCH 2/2] modernize comments about typing modes --- .../rustc_trait_selection/src/traits/coherence.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 43a351fd14fba..484b16a1296d8 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -498,8 +498,8 @@ fn impl_intersection_has_negative_obligation( ) -> bool { debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id); - // N.B. We need to unify impl headers *with* intercrate mode, even if proving negative predicates - // do not need intercrate mode enabled. + // N.B. We need to unify impl headers *with* `TypingMode::Coherence`, + // even if proving negative predicates doesn't need `TypingMode::Coherence`. let ref infcx = tcx.infer_ctxt().with_next_trait_solver(true).build(TypingMode::Coherence); let root_universe = infcx.universe(); assert_eq!(root_universe, ty::UniverseIndex::ROOT); @@ -529,8 +529,13 @@ fn impl_intersection_has_negative_obligation( (impl1_header.impl_args, impl2_header.impl_args), ); - assert!(!impl1_header.impl_args.has_non_region_infer()); + // Right above we plug inference variables with placeholders, + // this gets us new impl1_header_args with the inference variables actually resolved + // to those placeholders. let impl1_header_args = infcx.resolve_vars_if_possible(impl1_header.impl_args); + // So there are no infer variables left now, except regions which aren't resolved by `resolve_vars_if_possible`. + assert!(!impl1_header_args.has_non_region_infer()); + let param_env = ty::EarlyBinder::bind(tcx.param_env(impl1_def_id)).instantiate(tcx, impl1_header_args);