Skip to content

Commit 8dd9467

Browse files
compiler-errorsChayimFriedman2
authored andcommitted
Dont bail in error predicate unless self ty is error
1 parent e7815e5 commit 8dd9467

6 files changed

Lines changed: 29 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
@@ -224,6 +224,7 @@ where
224224
/// but prevents incorrect normalization while hiding any trait errors.
225225
fn consider_error_guaranteed_candidate(
226226
ecx: &mut EvalCtxt<'_, D>,
227+
goal: Goal<I, Self>,
227228
guar: I::ErrorGuaranteed,
228229
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased>;
229230

@@ -578,8 +579,8 @@ where
578579
// Instead of adding the logic here, it's a better idea to add it in
579580
// `EvalCtxt::disqualify_auto_trait_candidate_due_to_possible_impl` in
580581
// `solve::trait_goals` instead.
581-
let result = if let Err(guar) = goal.predicate.error_reported() {
582-
G::consider_error_guaranteed_candidate(self, guar)
582+
let result = if let ty::Error(guar) = goal.predicate.self_ty().kind() {
583+
G::consider_error_guaranteed_candidate(self, goal, guar)
583584
} else if cx.trait_is_auto(trait_def_id) {
584585
G::consider_auto_trait_candidate(self, goal)
585586
} 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
@@ -191,6 +191,7 @@ where
191191

192192
fn consider_error_guaranteed_candidate(
193193
ecx: &mut EvalCtxt<'_, D>,
194+
_goal: Goal<I, Self>,
194195
_guar: I::ErrorGuaranteed,
195196
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
196197
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,21 @@ where
436436
/// Fail to normalize if the predicate contains an error, alternatively, we could normalize to `ty::Error`
437437
/// and succeed. Can experiment with this to figure out what results in better error messages.
438438
fn consider_error_guaranteed_candidate(
439-
_ecx: &mut EvalCtxt<'_, D>,
440-
_guar: I::ErrorGuaranteed,
439+
ecx: &mut EvalCtxt<'_, D>,
440+
goal: Goal<I, Self>,
441+
guar: I::ErrorGuaranteed,
441442
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
442-
Err(NoSolution.into())
443+
let cx = ecx.cx();
444+
let error_term = match goal.predicate.alias.kind {
445+
ty::AliasTermKind::ProjectionTy { .. } => Ty::new_error(cx, guar).into(),
446+
ty::AliasTermKind::ProjectionConst { .. } => Const::new_error(cx, guar).into(),
447+
kind => panic!("expected projection, found {kind:?}"),
448+
};
449+
450+
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
451+
ecx.instantiate_normalizes_to_term(goal, error_term);
452+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
453+
})
443454
}
444455

445456
fn consider_auto_trait_candidate(

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

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

126126
fn consider_error_guaranteed_candidate(
127127
ecx: &mut EvalCtxt<'_, D>,
128+
_goal: Goal<I, Self>,
128129
_guar: I::ErrorGuaranteed,
129130
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
130131
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
@@ -454,6 +454,15 @@ impl<I: Interner> CoroutineClosureSignature<I> {
454454
coroutine_captures_by_ref_ty: I::Ty,
455455
env_region: I::Region,
456456
) -> I::Ty {
457+
// If either of the tupled capture types are constrained to error
458+
// (e.g. during typeck when the infcx is tainted), then just return
459+
// the error type directly.
460+
if let ty::Error(_) = tupled_inputs_ty.kind() {
461+
return tupled_inputs_ty;
462+
} else if let ty::Error(_) = coroutine_captures_by_ref_ty.kind() {
463+
return coroutine_captures_by_ref_ty;
464+
}
465+
457466
match kind {
458467
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
459468
let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else {

tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl X for Y {
2929
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
3030
//~^ ERROR method `line_stream` is not a member of trait `X`
3131
//[current]~^^ ERROR `()` is not a future
32-
//[next]~^^^ ERROR: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
32+
//[next]~^^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _` [E0271]
3333
}
3434

3535
pub fn main() {}

0 commit comments

Comments
 (0)