Return correct error term kind on projection errors

This commit is contained in:
Boxy 2025-05-21 18:37:39 +01:00
parent 356f2d0774
commit bc9cdc960f
4 changed files with 81 additions and 12 deletions

View file

@ -378,6 +378,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
term: projected_term,
obligations: mut projected_obligations,
})) => {
debug!("opt_normalize_projection_type: progress");
// if projection succeeded, then what we get out of this
// is also non-normalized (consider: it was derived from
// an impl, where-clause etc) and hence we must
@ -408,6 +409,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
Ok(Some(result.value))
}
Ok(Projected::NoProgress(projected_ty)) => {
debug!("opt_normalize_projection_type: no progress");
let result =
Normalized { value: projected_ty, obligations: PredicateObligations::new() };
infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
@ -621,8 +623,17 @@ struct Progress<'tcx> {
}
impl<'tcx> Progress<'tcx> {
fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
Progress { term: Ty::new_error(tcx, guar).into(), obligations: PredicateObligations::new() }
fn error_for_term(
tcx: TyCtxt<'tcx>,
alias_term: ty::AliasTerm<'tcx>,
guar: ErrorGuaranteed,
) -> Self {
let err_term = if alias_term.kind(tcx).is_type() {
Ty::new_error(tcx, guar).into()
} else {
ty::Const::new_error(tcx, guar).into()
};
Progress { term: err_term, obligations: PredicateObligations::new() }
}
fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self {
@ -650,7 +661,11 @@ fn project<'cx, 'tcx>(
}
if let Err(guar) = obligation.predicate.error_reported() {
return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
return Ok(Projected::Progress(Progress::error_for_term(
selcx.tcx(),
obligation.predicate,
guar,
)));
}
let mut candidates = ProjectionCandidateSet::None;
@ -1965,7 +1980,13 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let param_env = obligation.param_env;
let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
Ok(assoc_term) => assoc_term,
Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))),
Err(guar) => {
return Ok(Projected::Progress(Progress::error_for_term(
tcx,
obligation.predicate,
guar,
)));
}
};
// This means that the impl is missing a definition for the

View file

@ -1,8 +0,0 @@
//@ known-bug: #140642
#![feature(min_generic_const_args)]
pub trait Tr<A> {
const SIZE: usize;
}
fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}

View file

@ -0,0 +1,17 @@
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
// Regression test for #140642. Test that normalizing const aliases
// containing erroneous types normalizes to a const error instead of
// a type error.
pub trait Tr<A> {
const SIZE: usize;
}
fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
//~^ ERROR: cannot find type `T` in this scope
//~| ERROR: cannot find type `T` in this scope
fn main() {}

View file

@ -0,0 +1,39 @@
error[E0412]: cannot find type `T` in this scope
--> $DIR/projection-error.rs:13:17
|
LL | pub trait Tr<A> {
| --------------- similarly named trait `Tr` defined here
...
LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
| ^
|
help: a trait with a similar name exists
|
LL | fn mk_array(_x: Tr) -> [(); <T as Tr<bool>>::SIZE] {}
| +
help: you might be missing a type parameter
|
LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
| +++
error[E0412]: cannot find type `T` in this scope
--> $DIR/projection-error.rs:13:29
|
LL | pub trait Tr<A> {
| --------------- similarly named trait `Tr` defined here
...
LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
| ^
|
help: a trait with a similar name exists
|
LL | fn mk_array(_x: T) -> [(); <Tr as Tr<bool>>::SIZE] {}
| +
help: you might be missing a type parameter
|
LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
| +++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0412`.