Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ where
/// but prevents incorrect normalization while hiding any trait errors.
fn consider_error_guaranteed_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
guar: I::ErrorGuaranteed,
) -> Result<Candidate<I>, NoSolution>;

Expand Down Expand Up @@ -532,8 +533,8 @@ where
// Instead of adding the logic here, it's a better idea to add it in
// `EvalCtxt::disqualify_auto_trait_candidate_due_to_possible_impl` in
// `solve::trait_goals` instead.
let result = if let Err(guar) = goal.predicate.error_reported() {
G::consider_error_guaranteed_candidate(self, guar)
let result = if let ty::Error(guar) = goal.predicate.self_ty().kind() {
G::consider_error_guaranteed_candidate(self, goal, guar)
} else if cx.trait_is_auto(trait_def_id) {
G::consider_auto_trait_candidate(self, goal)
} else if cx.trait_is_alias(trait_def_id) {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ where

fn consider_error_guaranteed_candidate(
ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
_guar: I::ErrorGuaranteed,
) -> Result<Candidate<I>, NoSolution> {
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,17 @@ where
/// Fail to normalize if the predicate contains an error, alternatively, we could normalize to `ty::Error`
/// and succeed. Can experiment with this to figure out what results in better error messages.
fn consider_error_guaranteed_candidate(
_ecx: &mut EvalCtxt<'_, D>,
_guar: I::ErrorGuaranteed,
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
guar: I::ErrorGuaranteed,
) -> Result<Candidate<I>, NoSolution> {
let cx = ecx.cx();
let error_term = match goal.predicate.alias.kind(cx) {
ty::AliasTermKind::ProjectionTy => Ty::new_error(cx, guar).into(),
ty::AliasTermKind::ProjectionConst => Const::new_error(cx, guar).into(),
kind => panic!("expected projection, found {kind:?}"),
};
ecx.instantiate_normalizes_to_term(goal, error_term);
Err(NoSolution)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why still return Err(NoSolution) instead of just succeeding after constraining the term to ty::Error

}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ where

fn consider_error_guaranteed_candidate(
ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
_guar: I::ErrorGuaranteed,
) -> Result<Candidate<I>, NoSolution> {
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_type_ir/src/ty_kind/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,15 @@ impl<I: Interner> CoroutineClosureSignature<I> {
coroutine_captures_by_ref_ty: I::Ty,
env_region: I::Region,
) -> I::Ty {
// If either of the tupled capture types are constrained to error
// (e.g. during typeck when the infcx is tainted), then just return
// the error type directly.
if let ty::Error(_) = tupled_inputs_ty.kind() {
return tupled_inputs_ty;
} else if let ty::Error(_) = coroutine_captures_by_ref_ty.kind() {
return coroutine_captures_by_ref_ty;
}

match kind {
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/traits/const-traits/call-const-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Bar for () {
const FOO: () = {
(const || ().foo())();
//~^ ERROR the trait bound `(): [const] Bar` is not satisfied
// FIXME(const_trait_impl): The constness environment for const closures is wrong.
//~| ERROR [const] Fn()` is not satisfied
};

fn main() {}
8 changes: 7 additions & 1 deletion tests/ui/traits/const-traits/call-const-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ help: make the `impl` of trait `Bar` `const`
LL | impl const Bar for () {
| +++++

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

error: aborting due to 2 previous errors

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