Skip to content

Commit c12a9e0

Browse files
Use ConstEvaluatable clause from env
1 parent ffaa32b commit c12a9e0

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

compiler/rustc_trait_selection/src/solve/mod.rs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -173,36 +173,61 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
173173
&mut self,
174174
Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>,
175175
) -> QueryResult<'tcx> {
176-
match ct.kind() {
177-
ty::ConstKind::Unevaluated(uv) => {
178-
// We never return `NoSolution` here as `try_const_eval_resolve` emits an
179-
// error itself when failing to evaluate, so emitting an additional fulfillment
180-
// error in that case is unnecessary noise. This may change in the future once
181-
// evaluation failures are allowed to impact selection, e.g. generic const
182-
// expressions in impl headers or `where`-clauses.
183-
184-
// FIXME(generic_const_exprs): Implement handling for generic
185-
// const expressions here.
186-
if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv, ct.ty()) {
187-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
188-
} else {
189-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
176+
let mut responses = vec![];
177+
178+
let resolve_response = self.probe_candidate("const-evaluatable via resolve").enter(|ecx| {
179+
match ct.kind() {
180+
ty::ConstKind::Unevaluated(uv) => {
181+
// We never return `NoSolution` here as `try_const_eval_resolve` emits an
182+
// error itself when failing to evaluate, so emitting an additional fulfillment
183+
// error in that case is unnecessary noise. This may change in the future once
184+
// evaluation failures are allowed to impact selection, e.g. generic const
185+
// expressions in impl headers or `where`-clauses.
186+
if let Some(_normalized) = ecx.try_const_eval_resolve(param_env, uv, ct.ty()) {
187+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
188+
} else {
189+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
190+
}
191+
}
192+
ty::ConstKind::Infer(_) => {
193+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
194+
}
195+
ty::ConstKind::Placeholder(_)
196+
| ty::ConstKind::Value(_)
197+
| ty::ConstKind::Error(_) => {
198+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
199+
}
200+
// We can freely ICE here as:
201+
// - `Param` gets replaced with a placeholder during canonicalization
202+
// - `Bound` cannot exist as we don't have a binder around the self Type
203+
// - `Expr` is part of `feature(generic_const_exprs)` and is not implemented yet
204+
ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Expr(_) => {
205+
bug!("unexpect const kind: {:?}", ct)
190206
}
191207
}
192-
ty::ConstKind::Infer(_) => {
193-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
194-
}
195-
ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
196-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
197-
}
198-
// We can freely ICE here as:
199-
// - `Param` gets replaced with a placeholder during canonicalization
200-
// - `Bound` cannot exist as we don't have a binder around the self Type
201-
// - `Expr` is part of `feature(generic_const_exprs)` and is not implemented yet
202-
ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Expr(_) => {
203-
bug!("unexpect const kind: {:?}", ct)
208+
});
209+
responses.extend(resolve_response);
210+
211+
// FIXME(generic_const_exprs): We don't walk into these candidates, though perhaps we should.
212+
for candidate in param_env.caller_bounds() {
213+
if let ty::ClauseKind::ConstEvaluatable(candidate_ct) = candidate.kind().skip_binder() {
214+
responses.extend(self.probe_candidate("const evaluatable via param-env").enter(
215+
|ecx| {
216+
let candidate_ct = ecx.instantiate_binder_with_placeholders(
217+
candidate.kind().rebind(candidate_ct),
218+
);
219+
ecx.eq(param_env, ct, candidate_ct)?;
220+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
221+
},
222+
))
204223
}
205224
}
225+
226+
if let Some(response) = self.try_merge_responses(&responses) {
227+
Ok(response)
228+
} else {
229+
self.flounder(&responses)
230+
}
206231
}
207232

208233
#[instrument(level = "debug", skip(self), ret)]

tests/ui/const-generics/issues/issue-105037.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
// revisions: current next
2+
//[next] compile-flags: -Ztrait-solver=next
13
// run-pass
4+
25
#![feature(generic_const_exprs)]
36
#![allow(incomplete_features)]
47
#![allow(dead_code)]

0 commit comments

Comments
 (0)