Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 05d17ac

Browse files
committedJun 1, 2024
Opt-in diagnostics reporting to avoid doing extra work in the new solver
1 parent 84d5118 commit 05d17ac

File tree

31 files changed

+199
-106
lines changed

31 files changed

+199
-106
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13471347
return;
13481348
};
13491349
// Try to find predicates on *generic params* that would allow copying `ty`
1350-
let ocx = ObligationCtxt::new(self.infcx);
1350+
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
13511351
let cause = ObligationCause::misc(span, self.mir_def_id());
13521352

13531353
ocx.register_bound(cause, self.param_env, ty, def_id);

‎compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ fn check_opaque_type_well_formed<'tcx>(
340340
.with_next_trait_solver(next_trait_solver)
341341
.with_opaque_type_inference(parent_def_id)
342342
.build();
343-
let ocx = ObligationCtxt::new(&infcx);
343+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
344344
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
345345

346346
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without

‎compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
735735
// which path expressions are getting called on and which path expressions are only used
736736
// as function pointers. This is required for correctness.
737737
let infcx = tcx.infer_ctxt().build();
738-
let ocx = ObligationCtxt::new(&infcx);
738+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
739739

740740
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
741741
let cause = ObligationCause::new(

‎compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ fn check_opaque_meets_bounds<'tcx>(
342342
let param_env = tcx.param_env(defining_use_anchor);
343343

344344
let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build();
345-
let ocx = ObligationCtxt::new(&infcx);
345+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
346346

347347
let args = match *origin {
348348
hir::OpaqueTyOrigin::FnReturn(parent)
@@ -1727,7 +1727,7 @@ pub(super) fn check_coroutine_obligations(
17271727
.with_opaque_type_inference(def_id)
17281728
.build();
17291729

1730-
let ocx = ObligationCtxt::new(&infcx);
1730+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
17311731
for (predicate, cause) in &typeck_results.coroutine_stalled_predicates {
17321732
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate));
17331733
}

‎compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hir::intravisit;
1010
use rustc_hir::{GenericParamKind, ImplItemKind};
1111
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1212
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
13-
use rustc_infer::traits::util;
13+
use rustc_infer::traits::{util, FulfillmentErrorLike};
1414
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1515
use rustc_middle::ty::fold::BottomUpFolder;
1616
use rustc_middle::ty::util::ExplicitSelf;
@@ -225,7 +225,7 @@ fn compare_method_predicate_entailment<'tcx>(
225225
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
226226

227227
let infcx = &tcx.infer_ctxt().build();
228-
let ocx = ObligationCtxt::new(infcx);
228+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
229229

230230
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
231231

@@ -493,7 +493,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
493493
);
494494

495495
let infcx = &tcx.infer_ctxt().build();
496-
let ocx = ObligationCtxt::new(infcx);
496+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
497497

498498
// Normalize the impl signature with fresh variables for lifetime inference.
499499
let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
@@ -764,17 +764,23 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
764764
Ok(&*tcx.arena.alloc(remapped_types))
765765
}
766766

767-
struct ImplTraitInTraitCollector<'a, 'tcx> {
768-
ocx: &'a ObligationCtxt<'a, 'tcx>,
767+
struct ImplTraitInTraitCollector<'a, 'tcx, E>
768+
where
769+
E: FulfillmentErrorLike<'tcx>,
770+
{
771+
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
769772
types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
770773
span: Span,
771774
param_env: ty::ParamEnv<'tcx>,
772775
body_id: LocalDefId,
773776
}
774777

775-
impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
778+
impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
779+
where
780+
E: FulfillmentErrorLike<'tcx>,
781+
{
776782
fn new(
777-
ocx: &'a ObligationCtxt<'a, 'tcx>,
783+
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
778784
span: Span,
779785
param_env: ty::ParamEnv<'tcx>,
780786
body_id: LocalDefId,
@@ -783,7 +789,10 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
783789
}
784790
}
785791

786-
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
792+
impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
793+
where
794+
E: FulfillmentErrorLike<'tcx>,
795+
{
787796
fn interner(&self) -> TyCtxt<'tcx> {
788797
self.ocx.infcx.tcx
789798
}
@@ -1777,7 +1786,7 @@ fn compare_const_predicate_entailment<'tcx>(
17771786
);
17781787

17791788
let infcx = tcx.infer_ctxt().build();
1780-
let ocx = ObligationCtxt::new(&infcx);
1789+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
17811790

17821791
let impl_ct_own_bounds = impl_ct_predicates.instantiate_own(tcx, impl_args);
17831792
for (predicate, span) in impl_ct_own_bounds {
@@ -1910,7 +1919,7 @@ fn compare_type_predicate_entailment<'tcx>(
19101919
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
19111920
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
19121921
let infcx = tcx.infer_ctxt().build();
1913-
let ocx = ObligationCtxt::new(&infcx);
1922+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
19141923

19151924
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
19161925

@@ -1977,7 +1986,7 @@ pub(super) fn check_type_bounds<'tcx>(
19771986
let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
19781987

19791988
let infcx = tcx.infer_ctxt().build();
1980-
let ocx = ObligationCtxt::new(&infcx);
1989+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
19811990

19821991
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
19831992
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized

‎compiler/rustc_hir_analysis/src/check/dropck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
123123
adt_to_impl_args: GenericArgsRef<'tcx>,
124124
) -> Result<(), ErrorGuaranteed> {
125125
let infcx = tcx.infer_ctxt().build();
126-
let ocx = ObligationCtxt::new(&infcx);
126+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
127127

128128
// Take the param-env of the adt and instantiate the args that show up in
129129
// the implementation's self type. This gives us the assumptions that the

‎compiler/rustc_hir_analysis/src/check/entry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
133133
main_diagnostics_def_id,
134134
ObligationCauseCode::MainFunctionType,
135135
);
136-
let ocx = traits::ObligationCtxt::new(&infcx);
136+
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
137137
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
138138
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
139139
let errors = ocx.select_all_or_error();

‎compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ pub fn check_function_signature<'tcx>(
599599
let param_env = ty::ParamEnv::empty();
600600

601601
let infcx = &tcx.infer_ctxt().build();
602-
let ocx = ObligationCtxt::new(infcx);
602+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
603603

604604
let actual_sig = tcx.fn_sig(fn_id).instantiate_identity();
605605

‎compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,21 @@ use rustc_trait_selection::traits::misc::{
3737
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
3838
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
3939
use rustc_trait_selection::traits::{
40-
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
40+
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
4141
};
4242
use rustc_type_ir::TypeFlags;
4343

4444
use std::cell::LazyCell;
4545
use std::ops::{ControlFlow, Deref};
4646

4747
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
48-
pub(super) ocx: ObligationCtxt<'a, 'tcx>,
48+
pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>,
4949
span: Span,
5050
body_def_id: LocalDefId,
5151
param_env: ty::ParamEnv<'tcx>,
5252
}
5353
impl<'a, 'tcx> Deref for WfCheckingCtxt<'a, 'tcx> {
54-
type Target = ObligationCtxt<'a, 'tcx>;
54+
type Target = ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>;
5555
fn deref(&self) -> &Self::Target {
5656
&self.ocx
5757
}
@@ -106,7 +106,7 @@ where
106106
{
107107
let param_env = tcx.param_env(body_def_id);
108108
let infcx = &tcx.infer_ctxt().build();
109-
let ocx = ObligationCtxt::new(infcx);
109+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
110110

111111
let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env };
112112

‎compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
267267
.join(", "),
268268
}));
269269
} else {
270-
let ocx = ObligationCtxt::new(&infcx);
270+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
271271
for field in coerced_fields {
272272
ocx.register_obligation(Obligation::new(
273273
tcx,
@@ -480,7 +480,7 @@ pub fn coerce_unsized_info<'tcx>(
480480
};
481481

482482
// Register an obligation for `A: Trait<B>`.
483-
let ocx = ObligationCtxt::new(&infcx);
483+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
484484
let cause = traits::ObligationCause::misc(span, impl_did);
485485
let obligation = Obligation::new(
486486
tcx,

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12981298
.copied()
12991299
.filter(|&(impl_, _)| {
13001300
infcx.probe(|_| {
1301-
let ocx = ObligationCtxt::new(infcx);
1301+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
13021302
let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
13031303

13041304
let impl_args = infcx.fresh_args_for_item(span, impl_);

‎compiler/rustc_hir_analysis/src/hir_wf_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn diagnostic_hir_wf_check<'tcx>(
6767
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
6868
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
6969
let infcx = self.tcx.infer_ctxt().build();
70-
let ocx = ObligationCtxt::new(&infcx);
70+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
7171

7272
let tcx_ty = self.icx.lower_ty(ty);
7373
// This visitor can walk into binders, resulting in the `tcx_ty` to

‎compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ fn get_impl_args(
196196
impl2_node: Node,
197197
) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> {
198198
let infcx = &tcx.infer_ctxt().build();
199-
let ocx = ObligationCtxt::new(infcx);
199+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
200200
let param_env = tcx.param_env(impl1_def_id);
201201
let impl1_span = tcx.def_span(impl1_def_id);
202202
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?;

‎compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3048,7 +3048,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30483048
self.commit_if_ok(|snapshot| {
30493049
let outer_universe = self.universe();
30503050

3051-
let ocx = ObligationCtxt::new(self);
3051+
let ocx = ObligationCtxt::new_with_diagnostics(self);
30523052
let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id);
30533053
let impl_trait_ref =
30543054
self.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(self.tcx, impl_args);

‎compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13901390

13911391
let mut result = ProbeResult::Match;
13921392
let cause = &self.misc(self.span);
1393-
let ocx = ObligationCtxt::new(self);
1393+
let ocx = ObligationCtxt::new_with_diagnostics(self);
13941394

13951395
let mut trait_predicate = None;
13961396
let (mut xform_self_ty, mut xform_ret_ty);

‎compiler/rustc_hir_typeck/src/op.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
928928
let (obligation, _) =
929929
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
930930
// FIXME: This should potentially just add the obligation to the `FnCtxt`
931-
let ocx = ObligationCtxt::new(&self.infcx);
931+
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
932932
ocx.register_obligation(obligation);
933933
Err(ocx.select_all_or_error())
934934
}

‎compiler/rustc_mir_transform/src/coroutine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,7 @@ fn check_field_tys_sized<'tcx>(
16081608
let infcx = tcx.infer_ctxt().ignoring_regions().build();
16091609
let param_env = tcx.param_env(def_id);
16101610

1611-
let ocx = ObligationCtxt::new(&infcx);
1611+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
16121612
for field_ty in &coroutine_layout.field_tys {
16131613
ocx.register_bound(
16141614
ObligationCause::new(

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2321,7 +2321,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23212321
let param_env = ty::ParamEnv::empty();
23222322

23232323
let infcx = tcx.infer_ctxt().build();
2324-
let ocx = ObligationCtxt::new(&infcx);
2324+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
23252325

23262326
let span = tcx.def_span(def_id);
23272327
let fresh_args = infcx.fresh_args_for_item(span, def_id.to_def_id());

‎compiler/rustc_passes/src/layout_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn ensure_wf<'tcx>(
5454
pred,
5555
);
5656
let infcx = tcx.infer_ctxt().build();
57-
let ocx = traits::ObligationCtxt::new(&infcx);
57+
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
5858
ocx.register_obligation(obligation);
5959
let errors = ocx.select_all_or_error();
6060
if !errors.is_empty() {

‎compiler/rustc_trait_selection/src/infer.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
use crate::solve::NextSolverError;
12
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
2-
use crate::traits::{self, ObligationCtxt, SelectionContext};
3+
use crate::traits::{
4+
self, FromSolverError, Obligation, ObligationCause, ObligationCtxt, OldSolverError,
5+
SelectionContext,
6+
};
37

48
use rustc_hir::def_id::DefId;
59
use rustc_hir::lang_items::LangItem;
6-
use rustc_infer::traits::Obligation;
710
use rustc_macros::extension;
811
use rustc_middle::arena::ArenaAllocatable;
912
use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
1013
use rustc_middle::traits::query::NoSolution;
11-
use rustc_middle::traits::ObligationCause;
1214
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
1315
use rustc_middle::ty::{GenericArg, Upcast};
1416
use rustc_span::DUMMY_SP;
@@ -94,7 +96,7 @@ impl<'tcx> InferCtxt<'tcx> {
9496
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
9597
)) {
9698
Ok(Some(selection)) => {
97-
let ocx = ObligationCtxt::new(self);
99+
let ocx = ObligationCtxt::new_with_diagnostics(self);
98100
ocx.register_obligations(selection.nested_obligations());
99101
Some(ocx.select_all_or_error())
100102
}
@@ -122,19 +124,21 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
122124
/// bound for the closure and in part because it is convenient to
123125
/// have `'tcx` be free on this function so that we can talk about
124126
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
125-
fn enter_canonical_trait_query<K, R>(
127+
fn enter_canonical_trait_query<K, R, E>(
126128
self,
127129
canonical_key: &Canonical<'tcx, K>,
128-
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
130+
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx, E>, K) -> Result<R, NoSolution>,
129131
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
130132
where
131133
K: TypeFoldable<TyCtxt<'tcx>>,
132134
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
133135
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
136+
E: FromSolverError<'tcx, NextSolverError<'tcx>>
137+
+ FromSolverError<'tcx, OldSolverError<'tcx>>,
134138
{
135139
let (infcx, key, canonical_inference_vars) =
136140
self.build_with_canonical(DUMMY_SP, canonical_key);
137-
let ocx = ObligationCtxt::new(&infcx);
141+
let ocx = ObligationCtxt::new_generic(&infcx);
138142
let value = operation(&ocx, key)?;
139143
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
140144
}

‎compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
1515
use rustc_middle::ty::{self, TyCtxt};
1616
use rustc_span::symbol::sym;
1717

18-
use crate::traits::FulfillmentError;
18+
use crate::traits::{FulfillmentError, ScrubbedTraitError};
1919

2020
use super::eval_ctxt::GenerateProofTree;
2121
use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
@@ -226,6 +226,17 @@ impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for FulfillmentError<'tc
226226
}
227227
}
228228

229+
impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError {
230+
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self {
231+
match error {
232+
NextSolverError::TrueError(_) => ScrubbedTraitError::TrueError,
233+
NextSolverError::Ambiguity(_) | NextSolverError::Overflow(_) => {
234+
ScrubbedTraitError::Ambiguity
235+
}
236+
}
237+
}
238+
}
239+
229240
fn fulfillment_error_for_no_solution<'tcx>(
230241
infcx: &InferCtxt<'tcx>,
231242
root_obligation: PredicateObligation<'tcx>,

‎compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use rustc_ast_ir::try_visit;
1313
use rustc_ast_ir::visit::VisitorResult;
1414
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
15+
use rustc_infer::traits::FulfillmentErrorLike as _;
1516
use rustc_macros::extension;
1617
use rustc_middle::traits::query::NoSolution;
1718
use rustc_middle::traits::solve::{inspect, QueryResult};

‎compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
360360
let infcx = selcx.infcx;
361361

362362
if infcx.next_trait_solver() {
363-
let ocx = ObligationCtxt::new(infcx);
363+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
364364
ocx.register_obligations(obligations.iter().cloned());
365365
let errors_and_ambiguities = ocx.select_all_or_error();
366366
// We only care about the obligations that are *definitely* true errors.

‎compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::cell::RefCell;
22
use std::fmt::Debug;
33

4-
use super::FulfillmentContext;
54
use super::{FromSolverError, TraitEngine};
5+
use super::{FulfillmentContext, ScrubbedTraitError};
66
use crate::regions::InferCtxtRegionExt;
77
use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
88
use crate::solve::NextSolverError;
@@ -21,6 +21,7 @@ use rustc_infer::infer::canonical::{
2121
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
2222
use rustc_infer::infer::RegionResolutionError;
2323
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
24+
use rustc_infer::traits::FulfillmentErrorLike;
2425
use rustc_macros::extension;
2526
use rustc_middle::arena::ArenaAllocatable;
2627
use rustc_middle::traits::query::NoSolution;
@@ -53,20 +54,36 @@ impl<
5354

5455
/// Used if you want to have pleasant experience when dealing
5556
/// with obligations outside of hir or mir typeck.
56-
pub struct ObligationCtxt<'a, 'tcx> {
57+
pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError> {
5758
pub infcx: &'a InferCtxt<'tcx>,
58-
engine: RefCell<Box<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>>,
59+
engine: RefCell<Box<dyn TraitEngine<'tcx, E>>>,
5960
}
6061

61-
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
62+
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>> {
63+
pub fn new_with_diagnostics(infcx: &'a InferCtxt<'tcx>) -> Self {
64+
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
65+
}
66+
}
67+
68+
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError> {
6269
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
63-
// TODO:
64-
Self {
65-
infcx,
66-
engine: RefCell::new(<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>::new(infcx)),
67-
}
70+
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
71+
}
72+
}
73+
74+
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
75+
where
76+
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
77+
{
78+
pub fn new_generic(infcx: &'a InferCtxt<'tcx>) -> Self {
79+
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
6880
}
81+
}
6982

83+
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
84+
where
85+
E: FulfillmentErrorLike<'tcx>,
86+
{
7087
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
7188
self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation);
7289
}
@@ -118,26 +135,6 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
118135
self.register_infer_ok_obligations(infer_ok)
119136
}
120137

121-
pub fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
122-
&self,
123-
cause: &ObligationCause<'tcx>,
124-
param_env: ty::ParamEnv<'tcx>,
125-
value: T,
126-
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
127-
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
128-
}
129-
130-
pub fn structurally_normalize(
131-
&self,
132-
cause: &ObligationCause<'tcx>,
133-
param_env: ty::ParamEnv<'tcx>,
134-
value: Ty<'tcx>,
135-
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
136-
self.infcx
137-
.at(cause, param_env)
138-
.structurally_normalize(value, &mut **self.engine.borrow_mut())
139-
}
140-
141138
pub fn eq<T: ToTrace<'tcx>>(
142139
&self,
143140
cause: &ObligationCause<'tcx>,
@@ -194,12 +191,12 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
194191
}
195192

196193
#[must_use]
197-
pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> {
194+
pub fn select_where_possible(&self) -> Vec<E> {
198195
self.engine.borrow_mut().select_where_possible(self.infcx)
199196
}
200197

201198
#[must_use]
202-
pub fn select_all_or_error(&self) -> Vec<FulfillmentError<'tcx>> {
199+
pub fn select_all_or_error(&self) -> Vec<E> {
203200
self.engine.borrow_mut().select_all_or_error(self.infcx)
204201
}
205202

@@ -244,6 +241,24 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
244241
self.infcx.resolve_regions(outlives_env)
245242
}
246243

244+
pub fn make_canonicalized_query_response<T>(
245+
&self,
246+
inference_vars: CanonicalVarValues<'tcx>,
247+
answer: T,
248+
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
249+
where
250+
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
251+
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
252+
{
253+
self.infcx.make_canonicalized_query_response(
254+
inference_vars,
255+
answer,
256+
&mut **self.engine.borrow_mut(),
257+
)
258+
}
259+
}
260+
261+
impl<'tcx> ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>> {
247262
pub fn assumed_wf_types_and_report_errors(
248263
&self,
249264
param_env: ty::ParamEnv<'tcx>,
@@ -252,12 +267,17 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
252267
self.assumed_wf_types(param_env, def_id)
253268
.map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(errors))
254269
}
270+
}
255271

272+
impl<'tcx, E> ObligationCtxt<'_, 'tcx, E>
273+
where
274+
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
275+
{
256276
pub fn assumed_wf_types(
257277
&self,
258278
param_env: ty::ParamEnv<'tcx>,
259279
def_id: LocalDefId,
260-
) -> Result<FxIndexSet<Ty<'tcx>>, Vec<FulfillmentError<'tcx>>> {
280+
) -> Result<FxIndexSet<Ty<'tcx>>, Vec<E>> {
261281
let tcx = self.infcx.tcx;
262282
let mut implied_bounds = FxIndexSet::default();
263283
let mut errors = Vec::new();
@@ -289,19 +309,23 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
289309
if errors.is_empty() { Ok(implied_bounds) } else { Err(errors) }
290310
}
291311

292-
pub fn make_canonicalized_query_response<T>(
312+
pub fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
293313
&self,
294-
inference_vars: CanonicalVarValues<'tcx>,
295-
answer: T,
296-
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
297-
where
298-
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
299-
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
300-
{
301-
self.infcx.make_canonicalized_query_response(
302-
inference_vars,
303-
answer,
304-
&mut **self.engine.borrow_mut(),
305-
)
314+
cause: &ObligationCause<'tcx>,
315+
param_env: ty::ParamEnv<'tcx>,
316+
value: T,
317+
) -> Result<T, Vec<E>> {
318+
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
319+
}
320+
321+
pub fn structurally_normalize(
322+
&self,
323+
cause: &ObligationCause<'tcx>,
324+
param_env: ty::ParamEnv<'tcx>,
325+
value: Ty<'tcx>,
326+
) -> Result<Ty<'tcx>, Vec<E>> {
327+
self.infcx
328+
.at(cause, param_env)
329+
.structurally_normalize(value, &mut **self.engine.borrow_mut())
306330
}
307331
}

‎compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ use rustc_middle::ty::GenericArgsRef;
1616
use rustc_middle::ty::{self, Binder, Const, TypeVisitableExt};
1717
use std::marker::PhantomData;
1818

19-
use super::const_evaluatable;
2019
use super::project::{self, ProjectAndUnifyResult};
2120
use super::select::SelectionContext;
2221
use super::wf;
2322
use super::EvaluationResult;
2423
use super::PredicateObligation;
2524
use super::Unimplemented;
25+
use super::{const_evaluatable, ScrubbedTraitError};
2626
use super::{FulfillmentError, FulfillmentErrorCode};
2727

2828
use crate::traits::project::PolyProjectionObligation;
@@ -855,3 +855,17 @@ impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx
855855
FulfillmentError::new(obligation, error.error, root_obligation)
856856
}
857857
}
858+
859+
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError {
860+
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
861+
match error.error {
862+
FulfillmentErrorCode::Select(_)
863+
| FulfillmentErrorCode::Project(_)
864+
| FulfillmentErrorCode::Subtype(_, _)
865+
| FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError,
866+
FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
867+
ScrubbedTraitError::Ambiguity
868+
}
869+
}
870+
}
871+
}

‎compiler/rustc_trait_selection/src/traits/misc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn all_fields_implement_trait<'tcx>(
137137
for field in &variant.fields {
138138
// Do this per-field to get better error messages.
139139
let infcx = tcx.infer_ctxt().build();
140-
let ocx = traits::ObligationCtxt::new(&infcx);
140+
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
141141

142142
let unnormalized_ty = field.ty(tcx, args);
143143
if unnormalized_ty.references_error() {

‎compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub use self::coherence::{add_placeholder_note, orphan_check_trait_ref, overlapp
4646
pub use self::coherence::{InCrate, IsFirstInputType, UncoveredTyParams};
4747
pub use self::coherence::{OrphanCheckErr, OrphanCheckMode, OverlapResult};
4848
pub use self::engine::{ObligationCtxt, TraitEngineExt};
49-
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
49+
pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation};
5050
pub use self::normalize::NormalizeExt;
5151
pub use self::object_safety::hir_ty_lowering_object_safety_violations;
5252
pub use self::object_safety::is_vtable_safe_method;
@@ -73,6 +73,28 @@ pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, Placeh
7373

7474
pub use rustc_infer::traits::*;
7575

76+
// A trait error without any information in it. You likely want to alternately use [`ObligationCtxt::new_with_diagnostics`] to get a [`FulfillmentError`].
77+
#[derive(Copy, Clone, Debug)]
78+
pub enum ScrubbedTraitError {
79+
TrueError,
80+
Ambiguity,
81+
}
82+
83+
impl ScrubbedTraitError {
84+
fn is_true_error(&self) -> bool {
85+
match self {
86+
ScrubbedTraitError::TrueError => true,
87+
ScrubbedTraitError::Ambiguity => false,
88+
}
89+
}
90+
}
91+
92+
impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError {
93+
fn is_true_error(&self) -> bool {
94+
self.is_true_error()
95+
}
96+
}
97+
7698
pub struct FulfillmentError<'tcx> {
7799
pub obligation: PredicateObligation<'tcx>,
78100
pub code: FulfillmentErrorCode<'tcx>,
@@ -453,7 +475,7 @@ pub fn fully_normalize<'tcx, T>(
453475
where
454476
T: TypeFoldable<TyCtxt<'tcx>>,
455477
{
456-
let ocx = ObligationCtxt::new(infcx);
478+
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
457479
debug!(?value);
458480
let normalized_value = ocx.normalize(&cause, param_env, value);
459481
debug!(?normalized_value);

‎compiler/rustc_traits/src/codegen.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ pub fn codegen_select_candidate<'tcx>(
5050
// Currently, we use a fulfillment context to completely resolve
5151
// all nested obligations. This is because they can inform the
5252
// inference of the impl's type parameters.
53-
let ocx = ObligationCtxt::new(&infcx);
53+
// FIXME(-Znext-solver): Doesn't need diagnostics if new solver.
54+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
5455
let impl_source = selection.map(|obligation| {
5556
ocx.register_obligation(obligation);
5657
});

‎compiler/rustc_traits/src/normalize_projection_ty.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_trait_selection::traits::query::{
88
normalize::NormalizationResult, CanonicalAliasGoal, NoSolution,
99
};
1010
use rustc_trait_selection::traits::{
11-
self, FulfillmentErrorCode, ObligationCause, SelectionContext,
11+
self, FulfillmentError, FulfillmentErrorCode, ObligationCause, ObligationCtxt, SelectionContext,
1212
};
1313
use tracing::debug;
1414

@@ -29,7 +29,8 @@ fn normalize_canonicalized_projection_ty<'tcx>(
2929

3030
tcx.infer_ctxt().enter_canonical_trait_query(
3131
&goal,
32-
|ocx, ParamEnvAnd { param_env, value: goal }| {
32+
|ocx: &ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>>,
33+
ParamEnvAnd { param_env, value: goal }| {
3334
debug_assert!(!ocx.infcx.next_trait_solver());
3435
let selcx = &mut SelectionContext::new(ocx.infcx);
3536
let cause = ObligationCause::dummy();
@@ -73,7 +74,7 @@ fn normalize_canonicalized_weak_ty<'tcx>(
7374

7475
tcx.infer_ctxt().enter_canonical_trait_query(
7576
&goal,
76-
|ocx, ParamEnvAnd { param_env, value: goal }| {
77+
|ocx: &ObligationCtxt<'_, 'tcx>, ParamEnvAnd { param_env, value: goal }| {
7778
let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.args).map(
7879
|(predicate, span)| {
7980
traits::Obligation::new(
@@ -99,7 +100,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>(
99100

100101
tcx.infer_ctxt().enter_canonical_trait_query(
101102
&goal,
102-
|ocx, ParamEnvAnd { param_env, value: goal }| {
103+
|ocx: &ObligationCtxt<'_, 'tcx>, ParamEnvAnd { param_env, value: goal }| {
103104
let selcx = &mut SelectionContext::new(ocx.infcx);
104105
let cause = ObligationCause::dummy();
105106
let mut obligations = vec![];

‎compiler/rustc_traits/src/type_op.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ fn type_op_eq<'tcx>(
4343
tcx: TyCtxt<'tcx>,
4444
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,
4545
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
46-
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
47-
let (param_env, Eq { a, b }) = key.into_parts();
48-
Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?)
49-
})
46+
tcx.infer_ctxt().enter_canonical_trait_query(
47+
&canonicalized,
48+
|ocx: &ObligationCtxt<'_, 'tcx>, key| {
49+
let (param_env, Eq { a, b }) = key.into_parts();
50+
Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?)
51+
},
52+
)
5053
}
5154

5255
fn type_op_normalize<'tcx, T>(
@@ -95,10 +98,13 @@ fn type_op_subtype<'tcx>(
9598
tcx: TyCtxt<'tcx>,
9699
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>,
97100
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
98-
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
99-
let (param_env, Subtype { sub, sup }) = key.into_parts();
100-
Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?)
101-
})
101+
tcx.infer_ctxt().enter_canonical_trait_query(
102+
&canonicalized,
103+
|ocx: &ObligationCtxt<'_, 'tcx>, key| {
104+
let (param_env, Subtype { sub, sup }) = key.into_parts();
105+
Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?)
106+
},
107+
)
102108
}
103109

104110
fn type_op_prove_predicate<'tcx>(

‎src/tools/clippy/clippy_lints/src/future_not_send.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
7979
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
8080
let span = decl.output.span();
8181
let infcx = cx.tcx.infer_ctxt().build();
82-
let ocx = ObligationCtxt::new(&infcx);
82+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
8383
let cause = traits::ObligationCause::misc(span, fn_def_id);
8484
ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);
8585
let send_errors = ocx.select_all_or_error();

0 commit comments

Comments
 (0)
This repository has been archived.