Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 791ce0b

Browse files
committed
remove some trait solver helpers
they add more complexity then they are worth. It's confusing which of these helpers should be used in which context.
1 parent 84c47b8 commit 791ce0b

File tree

31 files changed

+198
-288
lines changed

31 files changed

+198
-288
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_span::hygiene::DesugaringKind;
2424
use rustc_span::symbol::{kw, sym};
2525
use rustc_span::{BytePos, Span, Symbol};
2626
use rustc_trait_selection::infer::InferCtxtExt;
27+
use rustc_trait_selection::traits::ObligationCtxt;
2728

2829
use crate::borrow_set::TwoPhaseActivation;
2930
use crate::borrowck_errors;
@@ -760,20 +761,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
760761
else { return; };
761762
// Try to find predicates on *generic params* that would allow copying `ty`
762763
let infcx = tcx.infer_ctxt().build();
763-
let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
764-
let cause = ObligationCause::new(
765-
span,
766-
self.mir_def_id(),
767-
rustc_infer::traits::ObligationCauseCode::MiscObligation,
768-
);
769-
let errors = rustc_trait_selection::traits::fully_solve_bound(
770-
&infcx,
771-
cause,
772-
self.param_env,
773-
// Erase any region vids from the type, which may not be resolved
774-
infcx.tcx.erase_regions(ty),
775-
copy_did,
776-
);
764+
let ocx = ObligationCtxt::new(&infcx);
765+
let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span));
766+
let cause = ObligationCause::misc(span, self.mir_def_id());
767+
768+
ocx.register_bound(cause, self.param_env, infcx.tcx.erase_regions(ty), copy_did);
769+
let errors = ocx.select_all_or_error();
777770

778771
// Only emit suggestion if all required predicates are on generic
779772
let predicates: Result<Vec<_>, _> = errors

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10781078
self.param_env,
10791079
tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.erase_regions(ty)),
10801080
def_id,
1081-
DUMMY_SP,
10821081
)
10831082
}
10841083
_ => false,

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir;
99
use rustc_middle::mir::*;
1010
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
1111
use rustc_trait_selection::traits::{
12-
self, ImplSource, Obligation, ObligationCause, SelectionContext,
12+
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
1313
};
1414

1515
use super::ConstCx;
@@ -184,7 +184,10 @@ impl Qualif for NeedsNonConstDrop {
184184
}
185185

186186
// If we had any errors, then it's bad
187-
!traits::fully_solve_obligations(&infcx, impl_src.nested_obligations()).is_empty()
187+
let ocx = ObligationCtxt::new(&infcx);
188+
ocx.register_obligations(impl_src.nested_obligations());
189+
let errors = ocx.select_all_or_error();
190+
!errors.is_empty()
188191
}
189192

190193
fn in_adt_inherently<'tcx>(

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn equate_intrinsic_type<'tcx>(
5959
require_same_types(
6060
tcx,
6161
&cause,
62+
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
6263
tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id).subst_identity()),
6364
fty,
6465
);

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ use rustc_hir::ItemKind;
1111
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1212
use rustc_infer::infer::{self, RegionResolutionError};
1313
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
14+
use rustc_infer::traits::Obligation;
1415
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
1516
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
1617
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
1718
use rustc_trait_selection::traits::misc::{
1819
type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason,
1920
};
20-
use rustc_trait_selection::traits::predicate_for_trait_def;
21+
use rustc_trait_selection::traits::ObligationCtxt;
2122
use rustc_trait_selection::traits::{self, ObligationCause};
2223
use std::collections::BTreeMap;
2324

@@ -334,19 +335,19 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
334335
))
335336
.emit();
336337
} else {
337-
let errors = traits::fully_solve_obligations(
338-
&infcx,
339-
coerced_fields.into_iter().map(|field| {
340-
predicate_for_trait_def(
341-
tcx,
342-
param_env,
343-
cause.clone(),
338+
let ocx = ObligationCtxt::new(&infcx);
339+
for field in coerced_fields {
340+
ocx.register_obligation(Obligation::new(
341+
tcx,
342+
cause.clone(),
343+
param_env,
344+
ty::Binder::dummy(tcx.mk_trait_ref(
344345
dispatch_from_dyn_trait,
345-
0,
346346
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
347-
)
348-
}),
349-
);
347+
)),
348+
));
349+
}
350+
let errors = ocx.select_all_or_error();
350351
if !errors.is_empty() {
351352
infcx.err_ctxt().report_fulfillment_errors(&errors);
352353
}
@@ -583,10 +584,12 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
583584
};
584585

585586
// Register an obligation for `A: Trait<B>`.
587+
let ocx = ObligationCtxt::new(&infcx);
586588
let cause = traits::ObligationCause::misc(span, impl_did);
587-
let predicate =
588-
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
589-
let errors = traits::fully_solve_obligation(&infcx, predicate);
589+
let obligation =
590+
Obligation::new(tcx, cause, param_env, tcx.mk_trait_ref(trait_def_id, [source, target]));
591+
ocx.register_obligation(obligation);
592+
let errors = ocx.select_all_or_error();
590593
if !errors.is_empty() {
591594
infcx.err_ctxt().report_fulfillment_errors(&errors);
592595
}

compiler/rustc_hir_analysis/src/hir_wf_check.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_infer::traits::{ObligationCause, WellFormedLoc};
77
use rustc_middle::ty::query::Providers;
88
use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
99
use rustc_span::def_id::LocalDefId;
10-
use rustc_trait_selection::traits;
10+
use rustc_trait_selection::traits::{self, ObligationCtxt};
1111

1212
pub fn provide(providers: &mut Providers) {
1313
*providers = Providers { diagnostic_hir_wf_check, ..*providers };
@@ -66,35 +66,35 @@ fn diagnostic_hir_wf_check<'tcx>(
6666
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
6767
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
6868
let infcx = self.tcx.infer_ctxt().build();
69+
let ocx = ObligationCtxt::new(&infcx);
70+
6971
let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
7072
let cause = traits::ObligationCause::new(
7173
ty.span,
7274
self.def_id,
7375
traits::ObligationCauseCode::WellFormed(None),
7476
);
75-
let errors = traits::fully_solve_obligation(
76-
&infcx,
77-
traits::Obligation::new(
78-
self.tcx,
79-
cause,
80-
self.param_env,
81-
ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())),
82-
),
83-
);
84-
if !errors.is_empty() {
85-
debug!("Wf-check got errors for {:?}: {:?}", ty, errors);
86-
for error in errors {
87-
if error.obligation.predicate == self.predicate {
88-
// Save the cause from the greatest depth - this corresponds
89-
// to picking more-specific types (e.g. `MyStruct<u8>`)
90-
// over less-specific types (e.g. `Option<MyStruct<u8>>`)
91-
if self.depth >= self.cause_depth {
92-
self.cause = Some(error.obligation.cause);
93-
self.cause_depth = self.depth
94-
}
77+
78+
ocx.register_obligation(traits::Obligation::new(
79+
self.tcx,
80+
cause,
81+
self.param_env,
82+
ty::PredicateKind::WellFormed(tcx_ty.into()),
83+
));
84+
85+
for error in ocx.select_all_or_error() {
86+
debug!("Wf-check got error for {:?}: {:?}", ty, error);
87+
if error.obligation.predicate == self.predicate {
88+
// Save the cause from the greatest depth - this corresponds
89+
// to picking more-specific types (e.g. `MyStruct<u8>`)
90+
// over less-specific types (e.g. `Option<MyStruct<u8>>`)
91+
if self.depth >= self.cause_depth {
92+
self.cause = Some(error.obligation.cause);
93+
self.cause_depth = self.depth
9594
}
9695
}
9796
}
97+
9898
self.depth += 1;
9999
intravisit::walk_ty(self, ty);
100100
self.depth -= 1;

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use rustc_errors::ErrorGuaranteed;
102102
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
103103
use rustc_hir as hir;
104104
use rustc_hir::Node;
105-
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
105+
use rustc_infer::infer::TyCtxtInferExt;
106106
use rustc_macros::fluent_messages;
107107
use rustc_middle::middle;
108108
use rustc_middle::ty::query::Providers;
@@ -113,7 +113,7 @@ use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
113113
use rustc_span::{symbol::sym, Span, DUMMY_SP};
114114
use rustc_target::spec::abi::Abi;
115115
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
116-
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
116+
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
117117

118118
use std::ops::Not;
119119

@@ -160,24 +160,21 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
160160
fn require_same_types<'tcx>(
161161
tcx: TyCtxt<'tcx>,
162162
cause: &ObligationCause<'tcx>,
163+
param_env: ty::ParamEnv<'tcx>,
163164
expected: Ty<'tcx>,
164165
actual: Ty<'tcx>,
165-
) -> bool {
166+
) {
166167
let infcx = &tcx.infer_ctxt().build();
167-
let param_env = ty::ParamEnv::empty();
168-
let errors = match infcx.at(cause, param_env).eq(DefineOpaqueTypes::No, expected, actual) {
169-
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
168+
let ocx = ObligationCtxt::new(infcx);
169+
match ocx.eq(cause, param_env, expected, actual) {
170+
Ok(()) => {
171+
let errors = ocx.select_all_or_error();
172+
if !errors.is_empty() {
173+
infcx.err_ctxt().report_fulfillment_errors(&errors);
174+
}
175+
}
170176
Err(err) => {
171177
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
172-
return false;
173-
}
174-
};
175-
176-
match &errors[..] {
177-
[] => true,
178-
errors => {
179-
infcx.err_ctxt().report_fulfillment_errors(errors);
180-
false
181178
}
182179
}
183180
}
@@ -296,6 +293,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
296293
return;
297294
}
298295

296+
// Main should have no WC, so empty param env is OK here.
297+
let param_env = ty::ParamEnv::empty();
299298
let expected_return_type;
300299
if let Some(term_did) = tcx.lang_items().termination() {
301300
let return_ty = main_fnsig.output();
@@ -306,8 +305,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
306305
}
307306
let return_ty = return_ty.skip_binder();
308307
let infcx = tcx.infer_ctxt().build();
309-
// Main should have no WC, so empty param env is OK here.
310-
let param_env = ty::ParamEnv::empty();
311308
let cause = traits::ObligationCause::new(
312309
return_ty_span,
313310
main_diagnostics_def_id,
@@ -343,6 +340,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
343340
main_diagnostics_def_id,
344341
ObligationCauseCode::MainFunctionType,
345342
),
343+
param_env,
346344
se_ty,
347345
tcx.mk_fn_ptr(main_fnsig),
348346
);
@@ -417,6 +415,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
417415
start_def_id,
418416
ObligationCauseCode::StartFunctionType,
419417
),
418+
ty::ParamEnv::empty(), // start should not have any where bounds.
420419
se_ty,
421420
tcx.mk_fn_ptr(tcx.fn_sig(start_def_id).subst_identity()),
422421
);

compiler/rustc_hir_typeck/src/callee.rs

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

669669
if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
670670
if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty)
671-
&& !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
671+
&& !self.type_is_sized_modulo_regions(self.param_env, output_ty)
672672
{
673673
let descr = match maybe_def {
674674
DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9696
let t = self.resolve_vars_if_possible(t);
9797
t.error_reported()?;
9898

99-
if self.type_is_sized_modulo_regions(self.param_env, t, span) {
99+
if self.type_is_sized_modulo_regions(self.param_env, t) {
100100
return Ok(Some(PointerKind::Thin));
101101
}
102102

@@ -722,7 +722,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
722722

723723
debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty);
724724

725-
if !fcx.type_is_sized_modulo_regions(fcx.param_env, self.cast_ty, self.span)
725+
if !fcx.type_is_sized_modulo_regions(fcx.param_env, self.cast_ty)
726726
&& !self.cast_ty.has_infer_types()
727727
{
728728
self.report_cast_to_unsized_type(fcx);

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_hir::Expr;
4646
use rustc_hir_analysis::astconv::AstConv;
4747
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
4848
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
49-
use rustc_infer::traits::Obligation;
49+
use rustc_infer::traits::{Obligation, PredicateObligation};
5050
use rustc_middle::lint::in_external_macro;
5151
use rustc_middle::ty::adjustment::{
5252
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
@@ -597,13 +597,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
597597
// and almost never more than 3. By using a SmallVec we avoid an
598598
// allocation, at the (very small) cost of (occasionally) having to
599599
// shift subsequent elements down when removing the front element.
600-
let mut queue: SmallVec<[_; 4]> = smallvec![traits::predicate_for_trait_def(
600+
let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new(
601601
self.tcx,
602-
self.fcx.param_env,
603602
cause,
604-
coerce_unsized_did,
605-
0,
606-
[coerce_source, coerce_target]
603+
self.fcx.param_env,
604+
self.tcx.mk_trait_ref(coerce_unsized_did, [coerce_source, coerce_target])
607605
)];
608606

609607
let mut has_unsized_tuple_coercion = false;
@@ -651,9 +649,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
651649
let self_ty = trait_pred.skip_binder().self_ty();
652650
let unsize_ty = trait_pred.skip_binder().trait_ref.substs[1].expect_ty();
653651
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
654-
match (&self_ty.kind(), &unsize_ty.kind()) {
655-
(ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
656-
if self.type_var_is_sized(*v) =>
652+
match (self_ty.kind(), unsize_ty.kind()) {
653+
(&ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
654+
if self.type_var_is_sized(v) =>
657655
{
658656
debug!("coerce_unsized: have sized infer {:?}", v);
659657
coercion.obligations.push(obligation);

compiler/rustc_hir_typeck/src/demand.rs

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

14811481
// For this suggestion to make sense, the type would need to be `Copy`,
14821482
// or we have to be moving out of a `Box<T>`
1483-
if self.type_is_copy_modulo_regions(self.param_env, expected, sp)
1483+
if self.type_is_copy_modulo_regions(self.param_env, expected)
14841484
// FIXME(compiler-errors): We can actually do this if the checked_ty is
14851485
// `steps` layers of boxes, not just one, but this is easier and most likely.
14861486
|| (checked_ty.is_box() && steps == 1)

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,7 @@ fn copy_or_move<'a, 'tcx>(
867867
mc: &mc::MemCategorizationContext<'a, 'tcx>,
868868
place_with_id: &PlaceWithHirId<'tcx>,
869869
) -> ConsumeMode {
870-
if !mc.type_is_copy_modulo_regions(
871-
place_with_id.place.ty(),
872-
mc.tcx().hir().span(place_with_id.hir_id),
873-
) {
870+
if !mc.type_is_copy_modulo_regions(place_with_id.place.ty()) {
874871
ConsumeMode::Move
875872
} else {
876873
ConsumeMode::Copy

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,11 +1011,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10111011
let mut suggest_copied_or_cloned = || {
10121012
let expr_inner_ty = substs.type_at(0);
10131013
let expected_inner_ty = expected_substs.type_at(0);
1014-
if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
1015-
&& self.can_eq(self.param_env, *ty, expected_inner_ty)
1014+
if let &ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
1015+
&& self.can_eq(self.param_env, ty, expected_inner_ty)
10161016
{
10171017
let def_path = self.tcx.def_path_str(adt_def.did());
1018-
if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) {
1018+
if self.type_is_copy_modulo_regions(self.param_env, ty) {
10191019
diag.span_suggestion_verbose(
10201020
expr.span.shrink_to_hi(),
10211021
format!(
@@ -1029,9 +1029,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10291029
&& rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
10301030
self,
10311031
self.param_env,
1032-
*ty,
1032+
ty,
10331033
clone_did,
1034-
expr.span
10351034
)
10361035
{
10371036
diag.span_suggestion_verbose(

0 commit comments

Comments
 (0)