Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit eee8b9c

Browse files
committedNov 9, 2021
Auto merge of #90700 - fee1-dead:select-returns-vec, r=davidtwco
Make `select_*` methods return `Vec` for `TraitEngine` This reduces some complexity as an empty vec means no errors and non-empty vec means errors occurred.
2 parents 214cd1f + d863021 commit eee8b9c

File tree

25 files changed

+149
-143
lines changed

25 files changed

+149
-143
lines changed
 

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
339339
// We generally shouldn't have errors here because the query was
340340
// already run, but there's no point using `delay_span_bug`
341341
// when we're going to emit an error here anyway.
342-
let _errors = fulfill_cx.select_all_or_error(infcx).err().unwrap_or_else(Vec::new);
342+
let _errors = fulfill_cx.select_all_or_error(infcx);
343343

344344
let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| {
345345
debug!("{:#?}", region_constraints);

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1054,8 +1054,9 @@ fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId)
10541054
let mut fulfillment_cx = traits::FulfillmentContext::new();
10551055
let sync_def_id = tcx.require_lang_item(LangItem::Sync, Some(body.span));
10561056
fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
1057-
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
1058-
infcx.report_fulfillment_errors(&err, None, false);
1057+
let errors = fulfillment_cx.select_all_or_error(&infcx);
1058+
if !errors.is_empty() {
1059+
infcx.report_fulfillment_errors(&errors, None, false);
10591060
}
10601061
});
10611062
}

‎compiler/rustc_infer/src/infer/canonical/query_response.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
108108
let tcx = self.tcx;
109109

110110
// Select everything, returning errors.
111-
let true_errors = fulfill_cx.select_where_possible(self).err().unwrap_or_else(Vec::new);
111+
let true_errors = fulfill_cx.select_where_possible(self);
112112
debug!("true_errors = {:#?}", true_errors);
113113

114114
if !true_errors.is_empty() {
@@ -118,7 +118,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
118118
}
119119

120120
// Anything left unselected *now* must be an ambiguity.
121-
let ambig_errors = fulfill_cx.select_all_or_error(self).err().unwrap_or_else(Vec::new);
121+
let ambig_errors = fulfill_cx.select_all_or_error(self);
122122
debug!("ambig_errors = {:#?}", ambig_errors);
123123

124124
let region_obligations = self.take_registered_region_obligations();

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

+5-10
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,25 @@ pub trait TraitEngine<'tcx>: 'tcx {
4646
obligation: PredicateObligation<'tcx>,
4747
);
4848

49-
fn select_all_or_error(
50-
&mut self,
51-
infcx: &InferCtxt<'_, 'tcx>,
52-
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
49+
fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>>;
5350

5451
fn select_all_with_constness_or_error(
5552
&mut self,
5653
infcx: &InferCtxt<'_, 'tcx>,
5754
_constness: hir::Constness,
58-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
55+
) -> Vec<FulfillmentError<'tcx>> {
5956
self.select_all_or_error(infcx)
6057
}
6158

62-
fn select_where_possible(
63-
&mut self,
64-
infcx: &InferCtxt<'_, 'tcx>,
65-
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
59+
fn select_where_possible(&mut self, infcx: &InferCtxt<'_, 'tcx>)
60+
-> Vec<FulfillmentError<'tcx>>;
6661

6762
// FIXME(fee1-dead) this should not provide a default body for chalk as chalk should be updated
6863
fn select_with_constness_where_possible(
6964
&mut self,
7065
infcx: &InferCtxt<'_, 'tcx>,
7166
_constness: hir::Constness,
72-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
67+
) -> Vec<FulfillmentError<'tcx>> {
7368
self.select_where_possible(infcx)
7469
}
7570

‎compiler/rustc_trait_selection/src/autoderef.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
152152
},
153153
cause,
154154
);
155-
if let Err(e) = fulfillcx.select_where_possible(&self.infcx) {
155+
let errors = fulfillcx.select_where_possible(&self.infcx);
156+
if !errors.is_empty() {
156157
// This shouldn't happen, except for evaluate/fulfill mismatches,
157158
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
158159
// by design).
159-
debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", e);
160+
debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", errors);
160161
return None;
161162
}
162163
let obligations = fulfillcx.pending_obligations();

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
187187
// an additional sanity check.
188188
let mut fulfill = FulfillmentContext::new();
189189
fulfill.register_bound(&infcx, full_env, ty, trait_did, ObligationCause::dummy());
190-
fulfill.select_all_or_error(&infcx).unwrap_or_else(|e| {
191-
panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, e)
192-
});
190+
let errors = fulfill.select_all_or_error(&infcx);
191+
192+
if !errors.is_empty() {
193+
panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors);
194+
}
193195

194196
let body_id_map: FxHashMap<_, _> = infcx
195197
.inner

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

+21-23
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,32 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
4949
self.obligations.insert(obligation);
5050
}
5151

52-
fn select_all_or_error(
53-
&mut self,
54-
infcx: &InferCtxt<'_, 'tcx>,
55-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
56-
self.select_where_possible(infcx)?;
57-
58-
if self.obligations.is_empty() {
59-
Ok(())
60-
} else {
61-
let errors = self
62-
.obligations
63-
.iter()
64-
.map(|obligation| FulfillmentError {
65-
obligation: obligation.clone(),
66-
code: FulfillmentErrorCode::CodeAmbiguity,
67-
// FIXME - does Chalk have a notation of 'root obligation'?
68-
// This is just for diagnostics, so it's okay if this is wrong
69-
root_obligation: obligation.clone(),
70-
})
71-
.collect();
72-
Err(errors)
52+
fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
53+
{
54+
let errors = self.select_where_possible(infcx);
55+
56+
if !errors.is_empty() {
57+
return errors;
58+
}
7359
}
60+
61+
// any remaining obligations are errors
62+
self.obligations
63+
.iter()
64+
.map(|obligation| FulfillmentError {
65+
obligation: obligation.clone(),
66+
code: FulfillmentErrorCode::CodeAmbiguity,
67+
// FIXME - does Chalk have a notation of 'root obligation'?
68+
// This is just for diagnostics, so it's okay if this is wrong
69+
root_obligation: obligation.clone(),
70+
})
71+
.collect()
7472
}
7573

7674
fn select_where_possible(
7775
&mut self,
7876
infcx: &InferCtxt<'_, 'tcx>,
79-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
77+
) -> Vec<FulfillmentError<'tcx>> {
8078
assert!(!infcx.is_in_snapshot());
8179

8280
let mut errors = Vec::new();
@@ -147,7 +145,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
147145
}
148146
}
149147

150-
if errors.is_empty() { Ok(()) } else { Err(errors) }
148+
errors
151149
}
152150

153151
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ where
120120
// In principle, we only need to do this so long as `result`
121121
// contains unbound type parameters. It could be a slight
122122
// optimization to stop iterating early.
123-
if let Err(errors) = fulfill_cx.select_all_or_error(infcx) {
123+
let errors = fulfill_cx.select_all_or_error(infcx);
124+
if !errors.is_empty() {
124125
infcx.tcx.sess.delay_span_bug(
125126
rustc_span::DUMMY_SP,
126127
&format!("Encountered errors `{:?}` resolving bounds after type-checking", errors),

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

+22-30
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
126126
}
127127

128128
/// Attempts to select obligations using `selcx`.
129-
fn select(
130-
&mut self,
131-
selcx: &mut SelectionContext<'a, 'tcx>,
132-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
129+
fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
133130
let span = debug_span!("select", obligation_forest_size = ?self.predicates.len());
134131
let _enter = span.enter();
135132

@@ -163,7 +160,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
163160
errors.len()
164161
);
165162

166-
if errors.is_empty() { Ok(()) } else { Err(errors) }
163+
errors
167164
}
168165
}
169166

@@ -223,41 +220,36 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
223220
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
224221
}
225222

226-
fn select_all_or_error(
227-
&mut self,
228-
infcx: &InferCtxt<'_, 'tcx>,
229-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
230-
self.select_where_possible(infcx)?;
231-
232-
let errors: Vec<_> = self
233-
.predicates
234-
.to_errors(CodeAmbiguity)
235-
.into_iter()
236-
.map(to_fulfillment_error)
237-
.collect();
238-
if errors.is_empty() { Ok(()) } else { Err(errors) }
223+
fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
224+
{
225+
let errors = self.select_where_possible(infcx);
226+
if !errors.is_empty() {
227+
return errors;
228+
}
229+
}
230+
231+
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
239232
}
240233

241234
fn select_all_with_constness_or_error(
242235
&mut self,
243236
infcx: &InferCtxt<'_, 'tcx>,
244237
constness: rustc_hir::Constness,
245-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
246-
self.select_with_constness_where_possible(infcx, constness)?;
247-
248-
let errors: Vec<_> = self
249-
.predicates
250-
.to_errors(CodeAmbiguity)
251-
.into_iter()
252-
.map(to_fulfillment_error)
253-
.collect();
254-
if errors.is_empty() { Ok(()) } else { Err(errors) }
238+
) -> Vec<FulfillmentError<'tcx>> {
239+
{
240+
let errors = self.select_with_constness_where_possible(infcx, constness);
241+
if !errors.is_empty() {
242+
return errors;
243+
}
244+
}
245+
246+
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
255247
}
256248

257249
fn select_where_possible(
258250
&mut self,
259251
infcx: &InferCtxt<'_, 'tcx>,
260-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
252+
) -> Vec<FulfillmentError<'tcx>> {
261253
let mut selcx = SelectionContext::new(infcx);
262254
self.select(&mut selcx)
263255
}
@@ -266,7 +258,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
266258
&mut self,
267259
infcx: &InferCtxt<'_, 'tcx>,
268260
constness: hir::Constness,
269-
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
261+
) -> Vec<FulfillmentError<'tcx>> {
270262
let mut selcx = SelectionContext::with_constness(infcx, constness);
271263
self.select(&mut selcx)
272264
}

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

+14-9
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,21 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
180180
// Note: we only assume something is `Copy` if we can
181181
// *definitively* show that it implements `Copy`. Otherwise,
182182
// assume it is move; linear is always ok.
183-
match fulfill_cx.select_all_or_error(infcx) {
184-
Ok(()) => {
183+
match fulfill_cx.select_all_or_error(infcx).as_slice() {
184+
[] => {
185185
debug!(
186186
"type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
187187
ty,
188188
infcx.tcx.def_path_str(def_id)
189189
);
190190
true
191191
}
192-
Err(e) => {
192+
errors => {
193193
debug!(
194-
"type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
195-
ty,
196-
infcx.tcx.def_path_str(def_id),
197-
e
194+
?ty,
195+
bound = %infcx.tcx.def_path_str(def_id),
196+
?errors,
197+
"type_known_to_meet_bound_modulo_regions"
198198
);
199199
false
200200
}
@@ -410,7 +410,10 @@ where
410410
}
411411

412412
debug!("fully_normalize: select_all_or_error start");
413-
fulfill_cx.select_all_or_error(infcx)?;
413+
let errors = fulfill_cx.select_all_or_error(infcx);
414+
if !errors.is_empty() {
415+
return Err(errors);
416+
}
414417
debug!("fully_normalize: select_all_or_error complete");
415418
let resolved_value = infcx.resolve_vars_if_possible(normalized_value);
416419
debug!("fully_normalize: resolved_value={:?}", resolved_value);
@@ -441,7 +444,9 @@ pub fn impossible_predicates<'tcx>(
441444
fulfill_cx.register_predicate_obligation(&infcx, obligation);
442445
}
443446

444-
fulfill_cx.select_all_or_error(&infcx).is_err()
447+
let errors = fulfill_cx.select_all_or_error(&infcx);
448+
449+
!errors.is_empty()
445450
});
446451
debug!("impossible_predicates = {:?}", result);
447452
result

‎compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,11 @@ fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
7777
let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?;
7878
debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id));
7979
fulfill_cx.register_predicate_obligations(infcx, obligations);
80-
if let Err(e) = fulfill_cx.select_all_or_error(infcx) {
80+
let errors = fulfill_cx.select_all_or_error(infcx);
81+
if !errors.is_empty() {
8182
infcx.tcx.sess.diagnostic().delay_span_bug(
8283
DUMMY_SP,
83-
&format!("errors selecting obligation during MIR typeck: {:?}", e),
84+
&format!("errors selecting obligation during MIR typeck: {:?}", errors),
8485
);
8586
}
8687

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

+12-13
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,18 @@ fn fulfill_implication<'a, 'tcx>(
225225
for oblig in obligations.chain(more_obligations) {
226226
fulfill_cx.register_predicate_obligation(&infcx, oblig);
227227
}
228-
match fulfill_cx.select_all_or_error(infcx) {
229-
Err(errors) => {
228+
match fulfill_cx.select_all_or_error(infcx).as_slice() {
229+
[] => {
230+
debug!(
231+
"fulfill_implication: an impl for {:?} specializes {:?}",
232+
source_trait_ref, target_trait_ref
233+
);
234+
235+
// Now resolve the *substitution* we built for the target earlier, replacing
236+
// the inference variables inside with whatever we got from fulfillment.
237+
Ok(infcx.resolve_vars_if_possible(target_substs))
238+
}
239+
errors => {
230240
// no dice!
231241
debug!(
232242
"fulfill_implication: for impls on {:?} and {:?}, \
@@ -238,17 +248,6 @@ fn fulfill_implication<'a, 'tcx>(
238248
);
239249
Err(())
240250
}
241-
242-
Ok(()) => {
243-
debug!(
244-
"fulfill_implication: an impl for {:?} specializes {:?}",
245-
source_trait_ref, target_trait_ref
246-
);
247-
248-
// Now resolve the *substitution* we built for the target earlier, replacing
249-
// the inference variables inside with whatever we got from fulfillment.
250-
Ok(infcx.resolve_vars_if_possible(target_substs))
251-
}
252251
}
253252
})
254253
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn type_marked_structural(
103103
//
104104
// 2. We are sometimes doing future-incompatibility lints for
105105
// now, so we do not want unconditional errors here.
106-
fulfillment_cx.select_all_or_error(infcx).is_ok()
106+
fulfillment_cx.select_all_or_error(infcx).is_empty()
107107
}
108108

109109
/// This implements the traversal over the structure of a given type to try to

‎compiler/rustc_traits/src/implied_outlives_bounds.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ fn compute_implied_outlives_bounds<'tcx>(
128128

129129
// Ensure that those obligations that we had to solve
130130
// get solved *here*.
131-
match fulfill_cx.select_all_or_error(infcx) {
132-
Ok(()) => Ok(implied_bounds),
133-
Err(_) => Err(NoSolution),
131+
match fulfill_cx.select_all_or_error(infcx).as_slice() {
132+
[] => Ok(implied_bounds),
133+
_ => Err(NoSolution),
134134
}
135135
}
136136

‎compiler/rustc_typeck/src/check/check.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,9 @@ fn check_opaque_meets_bounds<'tcx>(
663663

664664
// Check that all obligations are satisfied by the implementation's
665665
// version.
666-
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
667-
infcx.report_fulfillment_errors(errors, None, false);
666+
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
667+
if !errors.is_empty() {
668+
infcx.report_fulfillment_errors(&errors, None, false);
668669
}
669670

670671
// Finally, resolve all regions. This catches wily misuses of

‎compiler/rustc_typeck/src/check/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
950950
};
951951
let mut fcx = traits::FulfillmentContext::new_in_snapshot();
952952
fcx.register_predicate_obligations(self, ok.obligations);
953-
fcx.select_where_possible(&self).is_ok()
953+
fcx.select_where_possible(&self).is_empty()
954954
})
955955
}
956956

‎compiler/rustc_typeck/src/check/compare_method.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,9 @@ fn compare_predicate_entailment<'tcx>(
391391

392392
// Check that all obligations are satisfied by the implementation's
393393
// version.
394-
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
395-
infcx.report_fulfillment_errors(errors, None, false);
394+
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
395+
if !errors.is_empty() {
396+
infcx.report_fulfillment_errors(&errors, None, false);
396397
return Err(ErrorReported);
397398
}
398399

@@ -1094,8 +1095,9 @@ crate fn compare_const_impl<'tcx>(
10941095

10951096
// Check that all obligations are satisfied by the implementation's
10961097
// version.
1097-
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
1098-
infcx.report_fulfillment_errors(errors, None, false);
1098+
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
1099+
if !errors.is_empty() {
1100+
infcx.report_fulfillment_errors(&errors, None, false);
10991101
return;
11001102
}
11011103

@@ -1210,8 +1212,9 @@ fn compare_type_predicate_entailment<'tcx>(
12101212

12111213
// Check that all obligations are satisfied by the implementation's
12121214
// version.
1213-
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
1214-
infcx.report_fulfillment_errors(errors, None, false);
1215+
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
1216+
if !errors.is_empty() {
1217+
infcx.report_fulfillment_errors(&errors, None, false);
12151218
return Err(ErrorReported);
12161219
}
12171220

@@ -1427,10 +1430,10 @@ pub fn check_type_bounds<'tcx>(
14271430

14281431
// Check that all obligations are satisfied by the implementation's
14291432
// version.
1430-
if let Err(ref errors) =
1431-
inh.fulfillment_cx.borrow_mut().select_all_with_constness_or_error(&infcx, constness)
1432-
{
1433-
infcx.report_fulfillment_errors(errors, None, false);
1433+
let errors =
1434+
inh.fulfillment_cx.borrow_mut().select_all_with_constness_or_error(&infcx, constness);
1435+
if !errors.is_empty() {
1436+
infcx.report_fulfillment_errors(&errors, None, false);
14341437
return Err(ErrorReported);
14351438
}
14361439

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,10 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
113113
}
114114
}
115115

116-
if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
116+
let errors = fulfillment_cx.select_all_or_error(&infcx);
117+
if !errors.is_empty() {
117118
// this could be reached when we get lazy normalization
118-
infcx.report_fulfillment_errors(errors, None, false);
119+
infcx.report_fulfillment_errors(&errors, None, false);
119120
return Err(ErrorReported);
120121
}
121122

‎compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -642,11 +642,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
642642

643643
#[instrument(skip(self), level = "debug")]
644644
pub(in super::super) fn select_all_obligations_or_error(&self) {
645-
if let Err(errors) = self
645+
let errors = self
646646
.fulfillment_cx
647647
.borrow_mut()
648-
.select_all_with_constness_or_error(&self, self.inh.constness)
649-
{
648+
.select_all_with_constness_or_error(&self, self.inh.constness);
649+
650+
if !errors.is_empty() {
650651
self.report_fulfillment_errors(&errors, self.inh.body_id, false);
651652
}
652653
}
@@ -657,13 +658,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
657658
fallback_has_occurred: bool,
658659
mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
659660
) {
660-
let result = self
661+
let mut result = self
661662
.fulfillment_cx
662663
.borrow_mut()
663664
.select_with_constness_where_possible(self, self.inh.constness);
664-
if let Err(mut errors) = result {
665-
mutate_fulfillment_errors(&mut errors);
666-
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
665+
if !result.is_empty() {
666+
mutate_fulfillment_errors(&mut result);
667+
self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred);
667668
}
668669
}
669670

@@ -793,14 +794,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
793794
// we can. We don't care if some things turn
794795
// out unconstrained or ambiguous, as we're
795796
// just trying to get hints here.
796-
self.save_and_restore_in_snapshot_flag(|_| {
797+
let errors = self.save_and_restore_in_snapshot_flag(|_| {
797798
let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
798799
for obligation in ok.obligations {
799800
fulfill.register_predicate_obligation(self, obligation);
800801
}
801802
fulfill.select_where_possible(self)
802-
})
803-
.map_err(|_| ())?;
803+
});
804+
805+
if !errors.is_empty() {
806+
return Err(());
807+
}
804808
}
805809
Err(_) => return Err(()),
806810
}

‎compiler/rustc_typeck/src/check/op.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -826,10 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
826826
self.obligation_for_method(span, trait_did, lhs_ty, Some(other_tys));
827827
let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
828828
fulfill.register_predicate_obligation(self, obligation);
829-
Err(match fulfill.select_where_possible(&self.infcx) {
830-
Err(errors) => errors,
831-
_ => vec![],
832-
})
829+
Err(fulfill.select_where_possible(&self.infcx))
833830
}
834831
}
835832
}

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
263263
}
264264

265265
// Check that all transitive obligations are satisfied.
266-
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
266+
let errors = fulfill_cx.select_all_or_error(&infcx);
267+
if !errors.is_empty() {
267268
infcx.report_fulfillment_errors(&errors, None, false);
268269
}
269270

@@ -522,7 +523,8 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
522523
fulfill_cx.register_predicate_obligation(&infcx, predicate);
523524

524525
// Check that all transitive obligations are satisfied.
525-
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
526+
let errors = fulfill_cx.select_all_or_error(&infcx);
527+
if !errors.is_empty() {
526528
infcx.report_fulfillment_errors(&errors, None, false);
527529
}
528530

‎compiler/rustc_typeck/src/hir_wf_check.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ fn diagnostic_hir_wf_check<'tcx>(
8888
),
8989
);
9090

91-
if let Err(errors) = fulfill.select_all_or_error(&infcx) {
91+
let errors = fulfill.select_all_or_error(&infcx);
92+
if !errors.is_empty() {
9293
tracing::debug!("Wf-check got errors for {:?}: {:?}", ty, errors);
9394
for error in errors {
9495
if error.obligation.predicate == self.predicate {

‎compiler/rustc_typeck/src/lib.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ fn require_same_types<'tcx>(
157157
}
158158
}
159159

160-
match fulfill_cx.select_all_or_error(infcx) {
161-
Ok(()) => true,
162-
Err(errors) => {
163-
infcx.report_fulfillment_errors(&errors, None, false);
160+
match fulfill_cx.select_all_or_error(infcx).as_slice() {
161+
[] => true,
162+
errors => {
163+
infcx.report_fulfillment_errors(errors, None, false);
164164
false
165165
}
166166
}
@@ -352,8 +352,9 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
352352
term_id,
353353
cause,
354354
);
355-
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
356-
infcx.report_fulfillment_errors(&err, None, false);
355+
let errors = fulfillment_cx.select_all_or_error(&infcx);
356+
if !errors.is_empty() {
357+
infcx.report_fulfillment_errors(&errors, None, false);
357358
error = true;
358359
}
359360
});

‎compiler/rustc_typeck/src/outlives/outlives_bounds.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
8383
// variables. Process these constraints.
8484
let mut fulfill_cx = FulfillmentContext::new();
8585
fulfill_cx.register_predicate_obligations(self, result.obligations);
86-
if fulfill_cx.select_all_or_error(self).is_err() {
86+
let errors = fulfill_cx.select_all_or_error(self);
87+
if !errors.is_empty() {
8788
self.tcx.sess.delay_span_bug(
8889
span,
8990
"implied_outlives_bounds failed to solve obligations from instantiation",

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
7777
if is_future {
7878
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
7979
let span = decl.output.span();
80-
let send_result = cx.tcx.infer_ctxt().enter(|infcx| {
80+
let send_errors = cx.tcx.infer_ctxt().enter(|infcx| {
8181
let cause = traits::ObligationCause::misc(span, hir_id);
8282
let mut fulfillment_cx = traits::FulfillmentContext::new();
8383
fulfillment_cx.register_bound(&infcx, cx.param_env, ret_ty, send_trait, cause);
8484
fulfillment_cx.select_all_or_error(&infcx)
8585
});
86-
if let Err(send_errors) = send_result {
86+
if !send_errors.is_empty() {
8787
span_lint_and_then(
8888
cx,
8989
FUTURE_NOT_SEND,

0 commit comments

Comments
 (0)
Please sign in to comment.