Skip to content

Commit 48cec8c

Browse files
committed
Return correct error term kind on projection errors
1 parent 356f2d0 commit 48cec8c

File tree

4 files changed

+69
-12
lines changed

4 files changed

+69
-12
lines changed

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
378378
term: projected_term,
379379
obligations: mut projected_obligations,
380380
})) => {
381+
debug!("opt_normalize_projection_type: progress");
381382
// if projection succeeded, then what we get out of this
382383
// is also non-normalized (consider: it was derived from
383384
// an impl, where-clause etc) and hence we must
@@ -408,6 +409,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
408409
Ok(Some(result.value))
409410
}
410411
Ok(Projected::NoProgress(projected_ty)) => {
412+
debug!("opt_normalize_projection_type: no progress");
411413
let result =
412414
Normalized { value: projected_ty, obligations: PredicateObligations::new() };
413415
infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
@@ -621,8 +623,13 @@ struct Progress<'tcx> {
621623
}
622624

623625
impl<'tcx> Progress<'tcx> {
624-
fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
625-
Progress { term: Ty::new_error(tcx, guar).into(), obligations: PredicateObligations::new() }
626+
fn error(tcx: TyCtxt<'tcx>, alias_term: ty::AliasTerm<'tcx>, guar: ErrorGuaranteed) -> Self {
627+
let err_term = if alias_term.kind(tcx).is_type() {
628+
Ty::new_error(tcx, guar).into()
629+
} else {
630+
ty::Const::new_error(tcx, guar).into()
631+
};
632+
Progress { term: err_term, obligations: PredicateObligations::new() }
626633
}
627634

628635
fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self {
@@ -650,7 +657,7 @@ fn project<'cx, 'tcx>(
650657
}
651658

652659
if let Err(guar) = obligation.predicate.error_reported() {
653-
return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
660+
return Ok(Projected::Progress(Progress::error(selcx.tcx(), obligation.predicate, guar)));
654661
}
655662

656663
let mut candidates = ProjectionCandidateSet::None;
@@ -1965,7 +1972,9 @@ fn confirm_impl_candidate<'cx, 'tcx>(
19651972
let param_env = obligation.param_env;
19661973
let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
19671974
Ok(assoc_term) => assoc_term,
1968-
Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))),
1975+
Err(guar) => {
1976+
return Ok(Projected::Progress(Progress::error(tcx, obligation.predicate, guar)));
1977+
}
19691978
};
19701979

19711980
// This means that the impl is missing a definition for the

tests/crashes/140642.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(min_generic_const_args)]
2+
#![expect(incomplete_features)]
3+
4+
// Regression test for #140642. Test that normalizing const aliases
5+
// containing erroneous types normalizes to a const error instead of
6+
// a type error.
7+
8+
9+
pub trait Tr<A> {
10+
const SIZE: usize;
11+
}
12+
13+
fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
14+
//~^ ERROR: cannot find type `T` in this scope
15+
//~| ERROR: cannot find type `T` in this scope
16+
17+
fn main() {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0412]: cannot find type `T` in this scope
2+
--> $DIR/projection-error.rs:13:17
3+
|
4+
LL | pub trait Tr<A> {
5+
| --------------- similarly named trait `Tr` defined here
6+
...
7+
LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
8+
| ^
9+
|
10+
help: a trait with a similar name exists
11+
|
12+
LL | fn mk_array(_x: Tr) -> [(); <T as Tr<bool>>::SIZE] {}
13+
| +
14+
help: you might be missing a type parameter
15+
|
16+
LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
17+
| +++
18+
19+
error[E0412]: cannot find type `T` in this scope
20+
--> $DIR/projection-error.rs:13:29
21+
|
22+
LL | pub trait Tr<A> {
23+
| --------------- similarly named trait `Tr` defined here
24+
...
25+
LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
26+
| ^
27+
|
28+
help: a trait with a similar name exists
29+
|
30+
LL | fn mk_array(_x: T) -> [(); <Tr as Tr<bool>>::SIZE] {}
31+
| +
32+
help: you might be missing a type parameter
33+
|
34+
LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
35+
| +++
36+
37+
error: aborting due to 2 previous errors
38+
39+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)