Skip to content

Commit 646eaf3

Browse files
committed
extract fulfillment err creation
1 parent e75cb5d commit 646eaf3

File tree

1 file changed

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

1 file changed

+73
-82
lines changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

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

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

0 commit comments

Comments
 (0)