Skip to content

Commit fe9c130

Browse files
compiler-errorsChayimFriedman2
authored andcommitted
Dont bail in error predicate unless self ty is error
1 parent 23d01cd commit fe9c130

7 files changed

Lines changed: 32 additions & 6 deletions

File tree

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ where
197197
/// but prevents incorrect normalization while hiding any trait errors.
198198
fn consider_error_guaranteed_candidate(
199199
ecx: &mut EvalCtxt<'_, D>,
200+
goal: Goal<I, Self>,
200201
guar: I::ErrorGuaranteed,
201202
) -> Result<Candidate<I>, NoSolution>;
202203

@@ -532,8 +533,8 @@ where
532533
// Instead of adding the logic here, it's a better idea to add it in
533534
// `EvalCtxt::disqualify_auto_trait_candidate_due_to_possible_impl` in
534535
// `solve::trait_goals` instead.
535-
let result = if let Err(guar) = goal.predicate.error_reported() {
536-
G::consider_error_guaranteed_candidate(self, guar)
536+
let result = if let ty::Error(guar) = goal.predicate.self_ty().kind() {
537+
G::consider_error_guaranteed_candidate(self, goal, guar)
537538
} else if cx.trait_is_auto(trait_def_id) {
538539
G::consider_auto_trait_candidate(self, goal)
539540
} else if cx.trait_is_alias(trait_def_id) {

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ where
182182

183183
fn consider_error_guaranteed_candidate(
184184
ecx: &mut EvalCtxt<'_, D>,
185+
_goal: Goal<I, Self>,
185186
_guar: I::ErrorGuaranteed,
186187
) -> Result<Candidate<I>, NoSolution> {
187188
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,17 @@ where
396396
/// Fail to normalize if the predicate contains an error, alternatively, we could normalize to `ty::Error`
397397
/// and succeed. Can experiment with this to figure out what results in better error messages.
398398
fn consider_error_guaranteed_candidate(
399-
_ecx: &mut EvalCtxt<'_, D>,
400-
_guar: I::ErrorGuaranteed,
399+
ecx: &mut EvalCtxt<'_, D>,
400+
goal: Goal<I, Self>,
401+
guar: I::ErrorGuaranteed,
401402
) -> Result<Candidate<I>, NoSolution> {
403+
let cx = ecx.cx();
404+
let error_term = match goal.predicate.alias.kind(cx) {
405+
ty::AliasTermKind::ProjectionTy => Ty::new_error(cx, guar).into(),
406+
ty::AliasTermKind::ProjectionConst => Const::new_error(cx, guar).into(),
407+
kind => panic!("expected projection, found {kind:?}"),
408+
};
409+
ecx.instantiate_normalizes_to_term(goal, error_term);
402410
Err(NoSolution)
403411
}
404412

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ where
121121

122122
fn consider_error_guaranteed_candidate(
123123
ecx: &mut EvalCtxt<'_, D>,
124+
_goal: Goal<I, Self>,
124125
_guar: I::ErrorGuaranteed,
125126
) -> Result<Candidate<I>, NoSolution> {
126127
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)

compiler/rustc_type_ir/src/ty_kind/closure.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,15 @@ impl<I: Interner> CoroutineClosureSignature<I> {
462462
coroutine_captures_by_ref_ty: I::Ty,
463463
env_region: I::Region,
464464
) -> I::Ty {
465+
// If either of the tupled capture types are constrained to error
466+
// (e.g. during typeck when the infcx is tainted), then just return
467+
// the error type directly.
468+
if let ty::Error(_) = tupled_inputs_ty.kind() {
469+
return tupled_inputs_ty;
470+
} else if let ty::Error(_) = coroutine_captures_by_ref_ty.kind() {
471+
return coroutine_captures_by_ref_ty;
472+
}
473+
465474
match kind {
466475
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
467476
let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else {

tests/ui/traits/const-traits/call-const-closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl Bar for () {
1515
const FOO: () = {
1616
(const || ().foo())();
1717
//~^ ERROR the trait bound `(): [const] Bar` is not satisfied
18-
// FIXME(const_trait_impl): The constness environment for const closures is wrong.
18+
//~| ERROR [const] Fn()` is not satisfied
1919
};
2020

2121
fn main() {}

tests/ui/traits/const-traits/call-const-closure.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ help: make the `impl` of trait `Bar` `const`
99
LL | impl const Bar for () {
1010
| +++++
1111

12-
error: aborting due to 1 previous error
12+
error[E0277]: the trait bound `{closure@$DIR/call-const-closure.rs:17:6: 17:14}: [const] Fn()` is not satisfied
13+
--> $DIR/call-const-closure.rs:17:5
14+
|
15+
LL | (const || ().foo())();
16+
| ^^^^^^^^^^^^^^^^^^^^^
17+
18+
error: aborting due to 2 previous errors
1319

1420
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)