From b8f773d93add3ce4304ff6fe57aca9d115ec7636 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:25:42 -0700 Subject: [PATCH 1/5] always use next-solver in coherence --- .../src/coherence/orphan.rs | 2 +- .../src/traits/coherence.rs | 215 +++++------------- 2 files changed, 54 insertions(+), 163 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index c970799d318fe..5a297661a50de 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -321,7 +321,7 @@ fn orphan_check<'tcx>( // (1) Instantiate all generic params with fresh inference vars. let infcx = tcx .infer_ctxt() - .with_next_trait_solver(tcx.next_trait_solver_in_coherence()) + .with_next_trait_solver(true) .enable_next_solver_overflow_fcw(false) .build(TypingMode::Coherence); let cause = traits::ObligationCause::dummy(); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 24217aaf75fe7..d91e44c359c6f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -34,8 +34,7 @@ use crate::solve::{SolverDelegate, deeply_normalize_for_diagnostics, inspect}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{ - FulfillmentErrorCode, NormalizeExt, Obligation, ObligationCause, PredicateObligation, - SelectionContext, SkipLeakCheck, util, + FulfillmentErrorCode, Obligation, ObligationCause, PredicateObligation, SkipLeakCheck, util, }; /// The "header" of an impl is everything outside the body: a Self type, a trait @@ -80,21 +79,6 @@ pub(crate) fn suggest_increasing_recursion_limit<'tcx, G: EmissionGuarantee>( suggest_new_overflow_limit(tcx, err); } -#[derive(Debug, Clone, Copy)] -enum TrackAmbiguityCauses { - Yes, - No, -} - -impl TrackAmbiguityCauses { - fn is_yes(self) -> bool { - match self { - TrackAmbiguityCauses::Yes => true, - TrackAmbiguityCauses::No => false, - } - } -} - /// If there are types that satisfy both impls, returns `Some` /// with a suitably-freshened `ImplHeader` with those types /// instantiated. Otherwise, returns `None`. @@ -158,42 +142,7 @@ fn overlapping_impls( overlap_mode: OverlapMode, is_of_trait: bool, ) -> Option> { - if tcx.next_trait_solver_in_coherence() { - overlap( - tcx, - TrackAmbiguityCauses::Yes, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - ) - } else { - let _overlap_with_bad_diagnostics = overlap( - tcx, - TrackAmbiguityCauses::No, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - )?; - - // In the case where we detect an error, run the check again, but - // this time tracking intercrate ambiguity causes for better - // diagnostics. (These take time and can lead to false errors.) - let overlap = overlap( - tcx, - TrackAmbiguityCauses::Yes, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - ) - .unwrap(); - Some(overlap) - } + overlap(tcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode, is_of_trait) } fn fresh_impl_header<'tcx>( @@ -218,27 +167,11 @@ fn fresh_impl_header<'tcx>( } } -fn fresh_impl_header_normalized<'tcx>( - infcx: &InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - impl_def_id: DefId, - is_of_trait: bool, -) -> ImplHeader<'tcx> { - let header = fresh_impl_header(infcx, impl_def_id, is_of_trait); - - let InferOk { value: mut header, obligations } = - infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(header)); - - header.predicates.extend(obligations.into_iter().map(|o| o.predicate)); - header -} - /// Can both impl `a` and impl `b` be satisfied by a common type (including /// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls. #[instrument(level = "debug", skip(tcx))] fn overlap<'tcx>( tcx: TyCtxt<'tcx>, - track_ambiguity_causes: TrackAmbiguityCauses, skip_leak_check: SkipLeakCheck, impl1_def_id: DefId, impl2_def_id: DefId, @@ -261,13 +194,9 @@ fn overlap<'tcx>( let infcx = tcx .infer_ctxt() .skip_leak_check(skip_leak_check.is_yes()) - .with_next_trait_solver(tcx.next_trait_solver_in_coherence()) + .with_next_trait_solver(true) .enable_next_solver_overflow_fcw(false) .build(TypingMode::Coherence); - let selcx = &mut SelectionContext::new(&infcx); - if track_ambiguity_causes.is_yes() { - selcx.enable_tracking_intercrate_ambiguity_causes(); - } // For the purposes of this check, we don't bring any placeholder // types into scope; instead, we replace the generic types with @@ -275,21 +204,12 @@ fn overlap<'tcx>( // empty environment. let param_env = ty::ParamEnv::empty(); - let impl1_header = if tcx.next_trait_solver_in_coherence() { - fresh_impl_header(selcx.infcx, impl1_def_id, is_of_trait) - } else { - fresh_impl_header_normalized(selcx.infcx, param_env, impl1_def_id, is_of_trait) - }; - let impl2_header = if tcx.next_trait_solver_in_coherence() { - fresh_impl_header(selcx.infcx, impl2_def_id, is_of_trait) - } else { - fresh_impl_header_normalized(selcx.infcx, param_env, impl2_def_id, is_of_trait) - }; + let impl1_header = fresh_impl_header(&infcx, impl1_def_id, is_of_trait); + 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 mut obligations = - equate_impl_headers(selcx.infcx, param_env, &impl1_header, &impl2_header)?; + let mut obligations = equate_impl_headers(&infcx, param_env, &impl1_header, &impl2_header)?; debug!("overlap: unification check succeeded"); obligations.extend( @@ -300,7 +220,7 @@ fn overlap<'tcx>( let mut overflowing_predicates = Vec::new(); if overlap_mode.use_implicit_negative() { - match impl_intersection_has_impossible_obligation(selcx, &obligations) { + match impl_intersection_has_impossible_obligation(&infcx, &obligations) { IntersectionHasImpossibleObligations::Yes => return None, IntersectionHasImpossibleObligations::No { overflowing_predicates: p } => { overflowing_predicates = p @@ -317,10 +237,8 @@ fn overlap<'tcx>( let intercrate_ambiguity_causes = if !overlap_mode.use_implicit_negative() { Default::default() - } else if infcx.next_trait_solver() { - compute_intercrate_ambiguity_causes(&infcx, &obligations) } else { - selcx.take_intercrate_ambiguity_causes() + compute_intercrate_ambiguity_causes(&infcx, &obligations) }; debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes); @@ -336,9 +254,7 @@ fn overlap<'tcx>( let mut impl_header = infcx.resolve_vars_if_possible(impl1_header); // Deeply normalize the impl header for diagnostics, ignoring any errors if this fails. - if infcx.next_trait_solver() { - impl_header = deeply_normalize_for_diagnostics(&infcx, param_env, impl_header); - } + impl_header = deeply_normalize_for_diagnostics(&infcx, param_env, impl_header); Some(OverlapResult { impl_header, @@ -376,7 +292,7 @@ fn equate_impl_headers<'tcx>( enum IntersectionHasImpossibleObligations<'tcx> { Yes, No { - /// With `-Znext-solver=coherence`, some obligations may + /// With the next solver, some obligations may /// fail if only the user increased the recursion limit. /// /// We return those obligations here and mention them in the @@ -403,78 +319,53 @@ enum IntersectionHasImpossibleObligations<'tcx> { /// of the two impls above to be empty. /// /// Importantly, this works even if there isn't a `impl !Error for MyLocalType`. -#[instrument(level = "debug", skip(selcx), ret)] -fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, +#[instrument(level = "debug", skip(infcx), ret)] +fn impl_intersection_has_impossible_obligation<'a, 'tcx>( + infcx: &InferCtxt<'tcx>, obligations: &'a [PredicateObligation<'tcx>], ) -> IntersectionHasImpossibleObligations<'tcx> { - let infcx = selcx.infcx; - - if infcx.next_trait_solver() { - // A fast path optimization, try evaluating all goals with - // a very low recursion depth and bail if any of them don't - // hold. - if !obligations.iter().all(|o| { - <&SolverDelegate<'tcx>>::from(infcx) - .root_goal_may_hold_with_depth(8, Goal::new(infcx.tcx, o.param_env, o.predicate)) - }) { - return IntersectionHasImpossibleObligations::Yes; - } - - let ocx = ObligationCtxt::new(infcx); - ocx.register_obligations(obligations.iter().cloned()); - let hard_errors = ocx.try_evaluate_obligations(); - if let TraitErrors::HasErrors(hard_errors) = hard_errors { - assert!( - hard_errors.iter().all(|e| e.is_true_error()), - "should not have detected ambiguity during first pass" - ); - return IntersectionHasImpossibleObligations::Yes; - } + // A fast path optimization, try evaluating all goals with + // a very low recursion depth and bail if any of them don't + // hold. + if !obligations.iter().all(|o| { + <&SolverDelegate<'tcx>>::from(infcx) + .root_goal_may_hold_with_depth(8, Goal::new(infcx.tcx, o.param_env, o.predicate)) + }) { + return IntersectionHasImpossibleObligations::Yes; + } - // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer - // `FulfillmentError`. This is so that we can detect overflowing obligations - // without needing to run the `BestObligation` visitor on true errors. - let ambiguities = ocx.into_pending_obligations(); - let ocx = ObligationCtxt::new_with_diagnostics(infcx); - ocx.register_obligations(ambiguities); - let errors_and_ambiguities = ocx.evaluate_obligations_error_on_ambiguity(); - // We only care about the obligations that are *definitely* true errors. - // Ambiguities do not prove the disjointness of two impls. - let (errors, ambiguities): (Vec<_>, Vec<_>) = - errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); - assert!(errors.is_empty(), "should not have ambiguities during second pass"); - - IntersectionHasImpossibleObligations::No { - overflowing_predicates: ambiguities - .into_iter() - .filter(|error| { - matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) - }) - .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) - .collect(), - } - } else { - for obligation in obligations { - // We use `evaluate_root_obligation` to correctly track intercrate - // ambiguity clauses. - let evaluation_result = selcx.evaluate_root_obligation(obligation); - - match evaluation_result { - Ok(result) => { - if !result.may_apply() { - return IntersectionHasImpossibleObligations::Yes; - } - } - // If overflow occurs, we need to conservatively treat the goal as possibly holding, - // since there can be instantiations of this goal that don't overflow and result in - // success. While this isn't much of a problem in the old solver, since we treat overflow - // fatally, this still can be encountered: . - Err(_overflow) => {} - } - } + let ocx = ObligationCtxt::new(infcx); + ocx.register_obligations(obligations.iter().cloned()); + let hard_errors = ocx.try_evaluate_obligations(); + if let TraitErrors::HasErrors(hard_errors) = hard_errors { + assert!( + hard_errors.iter().all(|e| e.is_true_error()), + "should not have detected ambiguity during first pass" + ); + return IntersectionHasImpossibleObligations::Yes; + } - IntersectionHasImpossibleObligations::No { overflowing_predicates: Vec::new() } + // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer + // `FulfillmentError`. This is so that we can detect overflowing obligations + // without needing to run the `BestObligation` visitor on true errors. + let ambiguities = ocx.into_pending_obligations(); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); + ocx.register_obligations(ambiguities); + let errors_and_ambiguities = ocx.evaluate_obligations_error_on_ambiguity(); + // We only care about the obligations that are *definitely* true errors. + // Ambiguities do not prove the disjointness of two impls. + let (errors, ambiguities): (Vec<_>, Vec<_>) = + errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); + assert!(errors.is_empty(), "should not have ambiguities during second pass"); + + IntersectionHasImpossibleObligations::No { + overflowing_predicates: ambiguities + .into_iter() + .filter(|error| { + matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) + }) + .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) + .collect(), } } From ad90f1fed7ccd5c0adf49bf4ab9950ea62f1bc3c Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:26:21 -0700 Subject: [PATCH 2/5] remove `coherence` from `NextSolverConfig` --- compiler/rustc_interface/src/tests.rs | 8 ++++---- compiler/rustc_middle/src/ty/context.rs | 4 ---- compiler/rustc_session/src/config.rs | 13 ++++--------- compiler/rustc_session/src/options.rs | 9 ++++----- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d3c479f2a22f5..fe49a0b0304b0 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -855,7 +855,7 @@ fn test_unstable_options_tracking_hash() { // tidy-alphabetical-end // FIXME(#160895): We don't test this when the next-solver is enabled by default. if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_none() { - tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); + tracked!(next_solver, NextSolverConfig { globally: true }); } // tidy-alphabetical-start tracked!(no_generate_arange_section, true); @@ -945,7 +945,7 @@ fn test_edition_parsing() { #[test] fn test_assumptions_on_binders_enables_next_solver_globally() { - let globally = NextSolverConfig { coherence: true, globally: true }; + let globally = NextSolverConfig { globally: true }; let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // `-Zassumptions-on-binders` alone enables the next solver globally. @@ -957,8 +957,8 @@ fn test_assumptions_on_binders_enables_next_solver_globally() { // Flag order must not matter when both `-Zassumptions-on-binders` and `-Znext-solver` // are present. for args in [ - ["-Zassumptions-on-binders".to_string(), "-Znext-solver=coherence".to_string()], - ["-Znext-solver=coherence".to_string(), "-Zassumptions-on-binders".to_string()], + ["-Zassumptions-on-binders".to_string(), "-Znext-solver=globally".to_string()], + ["-Znext-solver=globally".to_string(), "-Zassumptions-on-binders".to_string()], ] { let matches = optgroups().parse(&args).unwrap(); let opts = build_session_options(&mut early_dcx, &matches); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7a3b4c7fbbeb8..b2e9dff83d9f3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2692,10 +2692,6 @@ impl<'tcx> TyCtxt<'tcx> { self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs() } - pub fn next_trait_solver_in_coherence(self) -> bool { - self.sess.opts.unstable_opts.next_solver.coherence - } - pub fn disable_trait_solver_fast_paths(self) -> bool { self.sess.opts.unstable_opts.disable_fast_paths } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a5053c408b155..95696e9b0ee42 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1022,10 +1022,7 @@ impl ExternEntry { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct NextSolverConfig { - /// Whether the new trait solver should be enabled in coherence. - pub coherence: bool = true, /// Whether the new trait solver should be enabled everywhere. - /// This is only `true` if `coherence` is also enabled. pub globally: bool = false, } @@ -1034,9 +1031,9 @@ pub struct NextSolverConfig { impl Default for NextSolverConfig { fn default() -> Self { if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_some() { - Self { coherence: true, globally: true } + Self { globally: true } } else { - Self { coherence: true, globally: false } + Self { globally: false } } } } @@ -2719,15 +2716,13 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M // parsing so the effective config is independent of flag order and so consumers that // read `next_solver.globally` directly (e.g. feature-gate checks) see the right value. if unstable_opts.assumptions_on_binders { - // `NextSolverConfig::default()` has `coherence: true`; the only way `coherence` is - // false here is an explicit `-Znext-solver=no`. - if !unstable_opts.next_solver.coherence { + if !unstable_opts.next_solver.globally { early_dcx.early_warn( "-Zassumptions-on-binders unconditionally enables the next trait solver; \ `-Znext-solver=no` is ignored", ); } - unstable_opts.next_solver = NextSolverConfig { coherence: true, globally: true }; + unstable_opts.next_solver = NextSolverConfig { globally: true }; } if unstable_opts.staticlib_hide_internal_symbols && !crate_types.contains(&CrateType::StaticLib) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 90459090ced87..3fd95d19f27ef 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -858,7 +858,7 @@ mod desc { pub(crate) const parse_unpretty: &str = "`string` or `string=string`"; pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; pub(crate) const parse_next_solver_config: &str = - "either `globally` (when used without an argument), `coherence` (default) or `no`"; + "either `globally` (when used without an argument), `coherence` or `no`"; pub(crate) const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub(crate) const parse_linker_plugin_lto: &str = @@ -1776,13 +1776,12 @@ pub mod parse { pub(crate) fn parse_next_solver_config(slot: &mut NextSolverConfig, v: Option<&str>) -> bool { if let Some(config) = v { *slot = match config { - "no" => NextSolverConfig { coherence: false, globally: false }, - "coherence" => NextSolverConfig { coherence: true, globally: false }, - "globally" => NextSolverConfig { coherence: true, globally: true }, + "no" | "coherence" => NextSolverConfig { globally: false }, + "globally" => NextSolverConfig { globally: true }, _ => return false, }; } else { - *slot = NextSolverConfig { coherence: true, globally: true }; + *slot = NextSolverConfig { globally: true }; } true From f6a02b03d356b1e4855f66b3d9802ec25823d72c Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:27:01 -0700 Subject: [PATCH 3/5] remove intercrate ambiguity cause tracking from the old solver --- compiler/rustc_trait_selection/src/lib.rs | 1 - .../src/traits/select/mod.rs | 91 ------------------- 2 files changed, 92 deletions(-) diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index bbaf683f4288a..fe7d1719edaf3 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -20,7 +20,6 @@ #![feature(iterator_try_reduce)] #![feature(option_into_flat_iter)] #![feature(try_blocks)] -#![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f1eaa50797c49..5657e158ecea5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -35,7 +35,6 @@ use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; use self::SelectionCandidate::*; -use super::coherence::{self, Conflict}; use super::project::ProjectionTermObligation; use super::util::closure_trait_ref_and_return_type; use super::{ @@ -106,14 +105,6 @@ pub struct SelectionContext<'cx, 'tcx> { /// require themselves. freshener: TypeFreshener<'cx, 'tcx>, - /// If `intercrate` is set, we remember predicates which were - /// considered ambiguous because of impls potentially added in other crates. - /// This is used in coherence to give improved diagnostics. - /// We don't do his until we detect a coherence error because it can - /// lead to false overflow results (#47139) and because always - /// computing it may negatively impact performance. - intercrate_ambiguity_causes: Option>>, - /// The mode that trait queries run in, which informs our error handling /// policy. In essence, canonicalized queries need their errors propagated /// rather than immediately reported because we do not have accurate spans. @@ -191,7 +182,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, freshener: TypeFreshener::new(infcx), - intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } } @@ -208,27 +198,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { query_mode, ..SelectionContext::new(infcx) } } - /// Enables tracking of intercrate ambiguity causes. See - /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. - pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert!(self.typing_mode().is_coherence()); - assert!(self.intercrate_ambiguity_causes.is_none()); - - self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); - debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); - } - - /// Gets the intercrate ambiguity causes collected since tracking - /// was enabled and disables tracking at the same time. If - /// tracking is not enabled, just returns an empty vector. - pub fn take_intercrate_ambiguity_causes( - &mut self, - ) -> FxIndexSet> { - assert!(self.typing_mode().is_coherence()); - - self.intercrate_ambiguity_causes.take().unwrap_or_default() - } - pub fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -365,42 +334,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if let Err(conflict) = self.is_knowable(stack) { - debug!("coherence stage: not knowable"); - if self.intercrate_ambiguity_causes.is_some() { - debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack) { - let mut no_candidates_apply = true; - - for c in candidate_set.vec.iter() { - if self.evaluate_candidate(stack, c)?.may_apply() { - no_candidates_apply = false; - break; - } - } - - if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = self.infcx.resolve_vars_if_possible( - stack.obligation.predicate.skip_binder().trait_ref, - ); - if !trait_ref.references_error() { - let self_ty = trait_ref.self_ty(); - let self_ty = self_ty.has_concrete_skeleton().then(|| self_ty); - let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_ref, self_ty } - } else { - IntercrateAmbiguityCause::DownstreamCrate { trait_ref, self_ty } - }; - debug!(?cause, "evaluate_stack: pushing cause"); - self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); - } - } - } - } - return Ok(None); - } - let candidate_set = self.assemble_candidates(stack)?; if candidate_set.ambiguous { @@ -1432,30 +1365,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates } - fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { - let obligation = &stack.obligation; - match self.typing_mode() { - TypingMode::Coherence => {} - TypingMode::Typeck { .. } - | TypingMode::PostTypeckUntilBorrowck { .. } - | TypingMode::Reflection - | TypingMode::PostBorrowck { .. } - | TypingMode::PostAnalysis - | TypingMode::Codegen => return Ok(()), - } - - debug!("is_knowable()"); - - let predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); - - // Okay to skip binder because of the nature of the - // trait-ref-is-knowable check, which does not care about - // bound regions. - let trait_ref = predicate.skip_binder().trait_ref; - - coherence::trait_ref_is_knowable(self.infcx, trait_ref, |ty| Ok::<_, !>(ty)).into_ok() - } - /// Returns `true` if the global caches can be used. fn can_use_global_caches( &self, From 332ee855585bd86580eab6e1b71a397fca7f2ccd Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:27:33 -0700 Subject: [PATCH 4/5] mark TypingMode::Coherence arms in the old solver as unreachable --- .../src/traits/fulfill.rs | 19 +++++++++--- .../src/traits/normalize.rs | 12 +++++--- .../src/traits/project.rs | 8 +++-- .../src/traits/query/normalize.rs | 6 ++-- .../src/traits/select/candidate_assembly.rs | 9 +++--- .../src/traits/select/mod.rs | 30 +++++++++++-------- 6 files changed, 55 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index bca336c2a0449..909ba4a9b498e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -175,12 +175,14 @@ where TypingMode::Typeck { defining_opaque_types_and_generators } => { defining_opaque_types_and_generators } - TypingMode::Coherence - | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } + TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => return Default::default(), + TypingMode::Coherence => { + unreachable!("old solver coherence") + } }; if stalled_coroutines.is_empty() { @@ -869,8 +871,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { trait_obligation: PolyTraitObligation<'tcx>, stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { + debug_assert!( + !self.selcx.typing_mode().is_coherence(), + "we do not expect to use old solver in coherence anymore" + ); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if infcx.predicate_must_hold_considering_regions(obligation) { @@ -922,9 +928,14 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { project_obligation: PolyProjectionObligation<'tcx>, stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { + debug_assert!( + !self.selcx.typing_mode().is_coherence(), + "we do not expect to use old solver in coherence anymore" + ); + let tcx = self.selcx.tcx(); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if infcx.predicate_must_hold_considering_regions(obligation) { diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index f00b300c7e971..c7913e4a37f00 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -139,11 +139,13 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( // so we can ignore those. match infcx.typing_mode_raw().assert_not_erased() { // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => {} + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } value.has_type_flags(flags) @@ -428,8 +430,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.selcx.typing_mode() { // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.super_fold_with(self), TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { @@ -451,6 +452,9 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx self.depth -= 1; folded_ty } + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index eaaf082b105c2..20e9a34b328b1 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1026,8 +1026,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. match selcx.typing_mode() { - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::Reflection | TypingMode::PostBorrowck { .. } => { @@ -1045,6 +1044,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.infcx.resolve_vars_if_possible(trait_ref); !poly_trait_ref.still_further_specializable() } + TypingMode::Coherence => { + unreachable!( + "we do not expect to use old solver in coherence anymore" + ) + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 489e4f7a93d53..1eb783dd182e5 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -214,8 +214,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { ty::Opaque { def_id } => { // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.infcx.typing_mode_raw().assert_not_erased() { - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.try_super_fold_with(self)?, @@ -251,6 +250,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { self.anon_depth -= 1; folded_ty? } + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 30700689a8ff0..316e28ef286aa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -845,6 +845,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => { + debug_assert!( + !self.typing_mode().is_coherence(), + "we do not expect to use old solver in coherence anymore" + ); + if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate { .. })) { // We do not generate an auto impl candidate for `impl Trait`s which already // reference our auto trait. @@ -855,10 +860,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // Note that this is only sound as projection candidates of opaque types // are always applicable for auto traits. - } else if self.typing_mode().is_coherence() { - // We do not emit auto trait candidates for opaque types in coherence. - // Doing so can result in weird dependency cycles. - candidates.ambiguous = true; } else if self.infcx.can_define_opaque_ty(def_id) { // We do not emit auto trait candidates for opaque types in their defining scope, as // we need to know the hidden type first, which we can't reliably know within the defining diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5657e158ecea5..295b61ec642a4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -933,8 +933,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: PolyTraitObligation<'tcx>, ) -> Result { - if !self.typing_mode().is_coherence() - && obligation.is_global() + debug_assert!( + !self.typing_mode().is_coherence(), + "we do not expect to use old solver in coherence anymore" + ); + + if obligation.is_global() && obligation.param_env.caller_bounds().all(|bound| bound.has_param()) { // If a param env has no global bounds, global obligations do not @@ -1379,13 +1383,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.typing_mode() { - // Avoid using the global cache during coherence and just rely - // on the local cache. It is really just a simplification to - // avoid us having to fear that coherence results "pollute" - // the master cache. Since coherence executes pretty quickly, - // it's not worth going to more trouble to increase the - // hit-rate, I don't think. - TypingMode::Coherence => false, // Avoid using the global cache when we're defining opaque types // as their hidden type may impact the result of candidate selection. // @@ -1411,6 +1408,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME(#132279): This is still incorrect as we treat opaque types // and default associated items differently between these two modes. TypingMode::PostAnalysis | TypingMode::Codegen => true, + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } @@ -2437,14 +2437,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> { return Err(()); } - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } | TypingMode::Codegen | TypingMode::ErasedNotCoherence(_) | TypingMode::Reflection | TypingMode::PostAnalysis => {} + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } Ok(Normalized { value: impl_args, obligations: nested_obligations }) @@ -2785,12 +2787,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> { TypingMode::Typeck { defining_opaque_types_and_generators: stalled_generators } => { def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) } - TypingMode::Coherence - | TypingMode::PostAnalysis + TypingMode::PostAnalysis | TypingMode::Reflection | TypingMode::Codegen | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } => false, + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } } From aa886b741412ef7cfefece9ca8a66390923548a1 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:28:41 -0700 Subject: [PATCH 5/5] bless tests --- .../assumptions_on_binders/alias_outlives.rs | 2 +- ...higher_ranked_alias_outlives_assumption.rs | 2 +- .../placeholder-assumptions-issue-157840.rs | 2 +- .../resolved-region-var-max-universe.rs | 2 +- .../test-infra-fails-properly.rs | 2 +- .../test-infra-works.rs | 2 +- .../type_relation_binders_inside_solver-1.rs | 2 +- .../type_relation_binders_inside_solver-2.rs | 2 +- .../type_relation_binders_inside_solver-3.rs | 2 +- .../generic_const_exprs/error_in_ty.rs | 2 -- .../generic_const_exprs/error_in_ty.stderr | 16 +++++----- tests/ui/error-codes/E0476.old.stderr | 31 ------------------- tests/ui/error-codes/E0476.rs | 2 -- .../{E0476.next.stderr => E0476.stderr} | 8 ++--- ...-124857-combine-effect-const-infer-vars.rs | 2 -- ...857-combine-effect-const-infer-vars.stderr | 2 +- .../traits/issue-90662-projection-caching.rs | 2 -- .../ambiguity-causes-canonical-state-ice-1.rs | 1 - .../ambiguity-causes-canonical-state-ice-2.rs | 2 -- ...iguity-causes-canonical-state-ice-2.stderr | 2 +- .../ambiguity-causes-visitor-hang.rs | 2 -- .../ambiguity-causes-visitor-hang.stderr | 2 +- .../coherence/coherence-fulfill-overflow.rs | 2 -- .../coherence-fulfill-overflow.stderr | 2 +- ...e-unknowable-does-not-eagerly-normalize.rs | 1 - .../dont-ice-on-assoc-projection.rs | 2 -- .../dont-ice-on-assoc-projection.stderr | 4 +-- .../normalize/indirectly-constrained-term.rs | 3 -- .../coherence-alias-hang-with-region.rs | 1 - ...cursion-limit-normalizes-to-constraints.rs | 1 - 30 files changed, 27 insertions(+), 81 deletions(-) delete mode 100644 tests/ui/error-codes/E0476.old.stderr rename tests/ui/error-codes/{E0476.next.stderr => E0476.stderr} (92%) diff --git a/tests/ui/assumptions_on_binders/alias_outlives.rs b/tests/ui/assumptions_on_binders/alias_outlives.rs index 0c2ed6585cf45..adbb953927cb3 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.rs +++ b/tests/ui/assumptions_on_binders/alias_outlives.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver // test that a `::Assoc: '!a_u1` constraint is considered to be satisfied // if there's a `T::Assoc: 'static` assumption in the root universe and if not that it is diff --git a/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs b/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs index 2f0f2ca8aab85..79bd3e5f96afb 100644 --- a/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs +++ b/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver //@ check-pass #![feature(generic_const_items)] diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs index f449e02baadb8..d54c1e77ba3ec 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver trait Trait {} diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs index 4668581cfc6e1..c0715aeb437b2 100644 --- a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver // Regression test for an ICE in the `MaxUniverse` region visitor. When computing // the max universe of a region constraint, a `ReVar` term could already have been diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs index c02f3bace5071..5bf283cfc0a33 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver #![feature(test_binder_constraints)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/test-infra-works.rs b/tests/ui/assumptions_on_binders/test-infra-works.rs index f172a112fdd43..0cd38d0e79eca 100644 --- a/tests/ui/assumptions_on_binders/test-infra-works.rs +++ b/tests/ui/assumptions_on_binders/test-infra-works.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver #![feature(test_binder_constraints, non_lifetime_binders)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs index fe5753c3c9970..ced411ac68f39 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver #![crate_type = "lib"] diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs index 78769282a3f4e..5bf8b8e68df3e 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver #![crate_type = "lib"] diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs index c1d4d0ed1c79f..35c3cb460f35b 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver #![crate_type = "lib"] diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs index 29ad935c0149c..9449153060db5 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index dea81894463b3..21ca0f6e04d97 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find value `x` in this scope - --> $DIR/error_in_ty.rs:6:31 + --> $DIR/error_in_ty.rs:4:31 | LL | pub struct A {} | ^ not found in this scope | note: similarly named const parameter `z` defined here - --> $DIR/error_in_ty.rs:6:20 + --> $DIR/error_in_ty.rs:4:20 | LL | pub struct A {} | ^ @@ -16,7 +16,7 @@ LL + pub struct A {} | error: `[usize; x]` is forbidden as the type of a const generic parameter - --> $DIR/error_in_ty.rs:6:23 + --> $DIR/error_in_ty.rs:4:23 | LL | pub struct A {} | ^^^^^^^^^^ @@ -28,31 +28,31 @@ LL + #![feature(min_adt_const_params)] | error[E0308]: mismatched types - --> $DIR/error_in_ty.rs:10:8 + --> $DIR/error_in_ty.rs:8:8 | LL | impl A<2> { | ^ expected `[usize; x]`, found integer | note: expected because of the type of the const parameter - --> $DIR/error_in_ty.rs:6:14 + --> $DIR/error_in_ty.rs:4:14 | LL | pub struct A {} | ^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/error_in_ty.rs:16:8 + --> $DIR/error_in_ty.rs:14:8 | LL | impl A<2> { | ^ expected `[usize; x]`, found integer | note: expected because of the type of the const parameter - --> $DIR/error_in_ty.rs:6:14 + --> $DIR/error_in_ty.rs:4:14 | LL | pub struct A {} | ^^^^^^^^^^^^^^^^^^^ error[E0592]: duplicate definitions with name `B` - --> $DIR/error_in_ty.rs:12:5 + --> $DIR/error_in_ty.rs:10:5 | LL | pub const fn B() {} | ^^^^^^^^^^^^^^^^ duplicate definitions for `B` diff --git a/tests/ui/error-codes/E0476.old.stderr b/tests/ui/error-codes/E0476.old.stderr deleted file mode 100644 index 454dbecc7d01f..0000000000000 --- a/tests/ui/error-codes/E0476.old.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>` - --> $DIR/E0476.rs:11:1 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T - where 'b: 'a, T: Unsize, T: ?Sized, U: ?Sized; - -error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type - --> $DIR/E0476.rs:11:1 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: object type is valid for the lifetime `'a` as defined here - --> $DIR/E0476.rs:11:6 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^ -note: source pointer is only valid for the lifetime `'b` as defined here - --> $DIR/E0476.rs:11:10 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0119, E0476. -For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs index 03656d28b2b99..d5e4b8d237274 100644 --- a/tests/ui/error-codes/E0476.rs +++ b/tests/ui/error-codes/E0476.rs @@ -1,5 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver=coherence #![feature(coerce_unsized)] #![feature(unsize)] diff --git a/tests/ui/error-codes/E0476.next.stderr b/tests/ui/error-codes/E0476.stderr similarity index 92% rename from tests/ui/error-codes/E0476.next.stderr rename to tests/ui/error-codes/E0476.stderr index 454dbecc7d01f..0378ac6e8ec91 100644 --- a/tests/ui/error-codes/E0476.next.stderr +++ b/tests/ui/error-codes/E0476.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>` - --> $DIR/E0476.rs:11:1 + --> $DIR/E0476.rs:9:1 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,18 +9,18 @@ LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S where 'b: 'a, T: Unsize, T: ?Sized, U: ?Sized; error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type - --> $DIR/E0476.rs:11:1 + --> $DIR/E0476.rs:9:1 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: object type is valid for the lifetime `'a` as defined here - --> $DIR/E0476.rs:11:6 + --> $DIR/E0476.rs:9:6 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^ note: source pointer is only valid for the lifetime `'b` as defined here - --> $DIR/E0476.rs:11:10 + --> $DIR/E0476.rs:9:10 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^ diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs index ba503be2aaff7..39d1840caf41e 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(const_trait_impl)] const trait Foo {} diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr index 97fdb4b287e8f..76520d1f4d89a 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `i32` - --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:9:1 + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:7:1 | LL | const impl Foo for i32 {} | ---------------------- first implementation here diff --git a/tests/ui/traits/issue-90662-projection-caching.rs b/tests/ui/traits/issue-90662-projection-caching.rs index 247cc78979a91..ba3b6e4e43b98 100644 --- a/tests/ui/traits/issue-90662-projection-caching.rs +++ b/tests/ui/traits/issue-90662-projection-caching.rs @@ -1,5 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver=coherence //@ check-pass // Regression test for issue #90662 diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs index 151c3b226c114..48b1a442bf41d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass // A regression test for #124791. Computing ambiguity causes diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs index b472499cb0bf7..28df3a39ddddf 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - // A regression test for #124791. Computing ambiguity causes // for the overlap of the `ToString` impls caused an ICE. #![crate_type = "lib"] diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr index 469f7a909b141..6200046baa65d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `str` - --> $DIR/ambiguity-causes-canonical-state-ice-2.rs:18:1 + --> $DIR/ambiguity-causes-canonical-state-ice-2.rs:16:1 | LL | impl + ?Sized> Overlap for T {} | --------------------------------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs index 54854b1b8a522..190531bc9201d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs @@ -4,8 +4,6 @@ // takes multiple minutes when doing so and less than a second // otherwise. -//@ compile-flags: -Znext-solver=coherence - trait RecursiveSuper: Super< A0 = Self::Assoc, diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr index 3731dc5b74ec0..467981efe2c99 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>` - --> $DIR/ambiguity-causes-visitor-hang.rs:53:1 + --> $DIR/ambiguity-causes-visitor-hang.rs:51:1 | LL | impl Overlap for T {} | ------------------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs index 3fd22c7dbf0c1..551fe619329ff 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(rustc_attrs)] #![rustc_no_implicit_bounds] #![recursion_limit = "10"] diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr index 1827533a84d90..ce210afa8d284 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/coherence-fulfill-overflow.rs:14:1 + --> $DIR/coherence-fulfill-overflow.rs:12:1 | LL | impl Trait for W {} | ---------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs b/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs index 13cdcc7d93e58..95916365a73f2 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs +++ b/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass //@ aux-build:coherence-unknowable-does-not-eagerly-normalize-dep.rs // diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs index cbe489a0430a8..6ad7893e32f1e 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - // Makes sure we don't ICE on associated const projection when the feature gate // is not enabled, since we should avoid encountering ICEs on stable if possible. diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr index 8334fdae94856..0edae35ea6159 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr @@ -1,5 +1,5 @@ error[E0658]: associated const equality is incomplete - --> $DIR/dont-ice-on-assoc-projection.rs:15:32 + --> $DIR/dont-ice-on-assoc-projection.rs:13:32 | LL | impl Foo for T where T: Bar {} | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | impl Foo for T where T: Bar {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0119]: conflicting implementations of trait `Foo` for type `()` - --> $DIR/dont-ice-on-assoc-projection.rs:15:1 + --> $DIR/dont-ice-on-assoc-projection.rs:13:1 | LL | impl Foo for () {} | --------------- first implementation here diff --git a/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs b/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs index 696d567db86d9..7a555b40bf6dd 100644 --- a/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs +++ b/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs @@ -1,6 +1,3 @@ -//@ revisions: current next -//@[next] compile-flags: -Znext-solver=coherence -//@ ignore-compare-mode-next-solver (explicit revisions) //@ check-pass // A regression test for `paperclip-core`. This previously failed to compile diff --git a/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs b/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs index 1df895d732a40..0ccb6f22cf965 100644 --- a/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs +++ b/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs @@ -1,6 +1,5 @@ //@ check-pass //@ revisions: ai ia ii -//@ compile-flags: -Znext-solver=coherence // Regression test for nalgebra hang . diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs index e5a57a44d4980..f084027acfe68 100644 --- a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass #![feature(rustc_attrs)] #![rustc_no_implicit_bounds]