Skip to content

Commit ef8e46f

Browse files
committed
extract fulfillment err creation
1 parent 1e6f371 commit ef8e46f

File tree

1 file changed

+73
-83
lines changed
  • compiler/rustc_trait_selection/src/solve

1 file changed

+73
-83
lines changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

+73-83
Original file line numberDiff line numberDiff line change
@@ -74,37 +74,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7474
fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
7575
self.obligations
7676
.drain(..)
77-
.map(|obligation| {
78-
let code = infcx.probe(|_| {
79-
match infcx
80-
.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::IfEnabled)
81-
.0
82-
{
83-
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => {
84-
FulfillmentErrorCode::Ambiguity { overflow: None }
85-
}
86-
Ok((
87-
_,
88-
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }),
89-
_,
90-
)) => FulfillmentErrorCode::Ambiguity {
91-
overflow: Some(suggest_increasing_limit),
92-
},
93-
Ok((_, Certainty::Yes, _)) => {
94-
bug!("did not expect successful goal when collecting ambiguity errors")
95-
}
96-
Err(_) => {
97-
bug!("did not expect selection error when collecting ambiguity errors")
98-
}
99-
}
100-
});
101-
102-
FulfillmentError {
103-
obligation: obligation.clone(),
104-
code,
105-
root_obligation: obligation,
106-
}
107-
})
77+
.map(|obligation| fulfillment_error_for_stalled(infcx, obligation))
10878
.collect()
10979
}
11080

@@ -127,58 +97,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
12797
let (changed, certainty, nested_goals) = match result {
12898
Ok(result) => result,
12999
Err(NoSolution) => {
130-
errors.push(FulfillmentError {
131-
obligation: obligation.clone(),
132-
code: match goal.predicate.kind().skip_binder() {
133-
ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
134-
FulfillmentErrorCode::ProjectionError(
135-
// FIXME: This could be a `Sorts` if the term is a type
136-
MismatchedProjectionTypes { err: TypeError::Mismatch },
137-
)
138-
}
139-
ty::PredicateKind::NormalizesTo(..) => {
140-
FulfillmentErrorCode::ProjectionError(
141-
MismatchedProjectionTypes { err: TypeError::Mismatch },
142-
)
143-
}
144-
ty::PredicateKind::AliasRelate(_, _, _) => {
145-
FulfillmentErrorCode::ProjectionError(
146-
MismatchedProjectionTypes { err: TypeError::Mismatch },
147-
)
148-
}
149-
ty::PredicateKind::Subtype(pred) => {
150-
let (a, b) = infcx.enter_forall_and_leak_universe(
151-
goal.predicate.kind().rebind((pred.a, pred.b)),
152-
);
153-
let expected_found = ExpectedFound::new(true, a, b);
154-
FulfillmentErrorCode::SubtypeError(
155-
expected_found,
156-
TypeError::Sorts(expected_found),
157-
)
158-
}
159-
ty::PredicateKind::Coerce(pred) => {
160-
let (a, b) = infcx.enter_forall_and_leak_universe(
161-
goal.predicate.kind().rebind((pred.a, pred.b)),
162-
);
163-
let expected_found = ExpectedFound::new(false, a, b);
164-
FulfillmentErrorCode::SubtypeError(
165-
expected_found,
166-
TypeError::Sorts(expected_found),
167-
)
168-
}
169-
ty::PredicateKind::Clause(_)
170-
| ty::PredicateKind::ObjectSafe(_)
171-
| ty::PredicateKind::Ambiguous => {
172-
FulfillmentErrorCode::SelectionError(
173-
SelectionError::Unimplemented,
174-
)
175-
}
176-
ty::PredicateKind::ConstEquate(..) => {
177-
bug!("unexpected goal: {goal:?}")
178-
}
179-
},
180-
root_obligation: obligation,
181-
});
100+
errors.push(fulfillment_error_for_no_solution(infcx, obligation));
182101
continue;
183102
}
184103
};
@@ -218,3 +137,74 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
218137
std::mem::take(&mut self.obligations)
219138
}
220139
}
140+
141+
fn fulfillment_error_for_no_solution<'tcx>(
142+
infcx: &InferCtxt<'tcx>,
143+
obligation: PredicateObligation<'tcx>,
144+
) -> FulfillmentError<'tcx> {
145+
let code = match obligation.predicate.kind().skip_binder() {
146+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
147+
FulfillmentErrorCode::ProjectionError(
148+
// FIXME: This could be a `Sorts` if the term is a type
149+
MismatchedProjectionTypes { err: TypeError::Mismatch },
150+
)
151+
}
152+
ty::PredicateKind::NormalizesTo(..) => {
153+
FulfillmentErrorCode::ProjectionError(MismatchedProjectionTypes {
154+
err: TypeError::Mismatch,
155+
})
156+
}
157+
ty::PredicateKind::AliasRelate(_, _, _) => {
158+
FulfillmentErrorCode::ProjectionError(MismatchedProjectionTypes {
159+
err: TypeError::Mismatch,
160+
})
161+
}
162+
ty::PredicateKind::Subtype(pred) => {
163+
let (a, b) = infcx.enter_forall_and_leak_universe(
164+
obligation.predicate.kind().rebind((pred.a, pred.b)),
165+
);
166+
let expected_found = ExpectedFound::new(true, a, b);
167+
FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
168+
}
169+
ty::PredicateKind::Coerce(pred) => {
170+
let (a, b) = infcx.enter_forall_and_leak_universe(
171+
obligation.predicate.kind().rebind((pred.a, pred.b)),
172+
);
173+
let expected_found = ExpectedFound::new(false, a, b);
174+
FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
175+
}
176+
ty::PredicateKind::Clause(_)
177+
| ty::PredicateKind::ObjectSafe(_)
178+
| ty::PredicateKind::Ambiguous => {
179+
FulfillmentErrorCode::SelectionError(SelectionError::Unimplemented)
180+
}
181+
ty::PredicateKind::ConstEquate(..) => {
182+
bug!("unexpected goal: {obligation:?}")
183+
}
184+
};
185+
FulfillmentError { root_obligation: obligation.clone(), code, obligation }
186+
}
187+
188+
fn fulfillment_error_for_stalled<'tcx>(
189+
infcx: &InferCtxt<'tcx>,
190+
obligation: PredicateObligation<'tcx>,
191+
) -> FulfillmentError<'tcx> {
192+
let code = infcx.probe(|_| {
193+
match infcx.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::Never).0 {
194+
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => {
195+
FulfillmentErrorCode::Ambiguity { overflow: None }
196+
}
197+
Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }), _)) => {
198+
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }
199+
}
200+
Ok((_, Certainty::Yes, _)) => {
201+
bug!("did not expect successful goal when collecting ambiguity errors")
202+
}
203+
Err(_) => {
204+
bug!("did not expect selection error when collecting ambiguity errors")
205+
}
206+
}
207+
});
208+
209+
FulfillmentError { obligation: obligation.clone(), code, root_obligation: obligation }
210+
}

0 commit comments

Comments
 (0)