Skip to content

Commit b93677c

Browse files
committed
Register ConstArgHasType obligation when normalizing inherent projection consts
1 parent d2f87ea commit b93677c

5 files changed

Lines changed: 85 additions & 1 deletion

File tree

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! 2. equate the self type, and
66
//! 3. instantiate and register where clauses.
77
8+
use rustc_type_ir::inherent::*;
89
use rustc_type_ir::{self as ty, Interner};
910

1011
use crate::delegate::SolverDelegate;
@@ -51,11 +52,20 @@ where
5152
.map(|pred| goal.with(cx, pred)),
5253
);
5354

54-
let normalized = if inherent.kind(cx).is_type() {
55+
let normalized: I::Term = if inherent.kind(cx).is_type() {
5556
cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into()
5657
} else {
5758
cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).into()
5859
};
60+
61+
if let Some(ct) = normalized.as_const() {
62+
let expected_ty = cx.type_of(inherent.def_id).instantiate(cx, inherent_args);
63+
self.add_goal(
64+
GoalSource::Misc,
65+
goal.with(cx, ty::ClauseKind::ConstArgHasType(ct, expected_ty)),
66+
);
67+
}
68+
5969
self.instantiate_normalizes_to_term(goal, normalized);
6070
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
6171
}

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,17 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
549549
tcx.const_of_item(alias_term.def_id).instantiate(tcx, args).into()
550550
};
551551

552+
if let Some(ct) = term.as_const() {
553+
let expected_ty = tcx.type_of(alias_term.def_id).instantiate(tcx, args);
554+
obligations.push(Obligation::with_depth(
555+
tcx,
556+
cause.clone(),
557+
depth + 1,
558+
param_env,
559+
ty::ClauseKind::ConstArgHasType(ct, expected_ty),
560+
));
561+
}
562+
552563
let mut term = selcx.infcx.resolve_vars_if_possible(term);
553564
if term.has_aliases() {
554565
term =
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: the constant `"this isn't a usize"` is not of type `usize`
2+
--> $DIR/type-const-inherent-value-type-mismatch.rs:14:5
3+
|
4+
LL | type const N: usize = "this isn't a usize";
5+
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&'static str`
6+
7+
error[E0308]: mismatched types
8+
--> $DIR/type-const-inherent-value-type-mismatch.rs:18:11
9+
|
10+
LL | fn f() -> [u8; const { Struct::N }] {}
11+
| - ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; const { Struct::N }]`, found `()`
12+
| |
13+
| implicitly returns `()` as its body has no tail or `return` expression
14+
15+
error: aborting due to 2 previous errors
16+
17+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0284]: type annotations needed: cannot normalize `f::{constant#0}`
2+
--> $DIR/type-const-inherent-value-type-mismatch.rs:18:11
3+
|
4+
LL | fn f() -> [u8; const { Struct::N }] {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `f::{constant#0}`
6+
7+
error: the constant `"this isn't a usize"` is not of type `usize`
8+
--> $DIR/type-const-inherent-value-type-mismatch.rs:14:5
9+
|
10+
LL | type const N: usize = "this isn't a usize";
11+
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&'static str`
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/type-const-inherent-value-type-mismatch.rs:18:11
15+
|
16+
LL | fn f() -> [u8; const { Struct::N }] {}
17+
| - ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; const { Struct::N }]`, found `()`
18+
| |
19+
| implicitly returns `()` as its body has no tail or `return` expression
20+
21+
error: aborting due to 3 previous errors
22+
23+
Some errors have detailed explanations: E0284, E0308.
24+
For more information about an error, try `rustc --explain E0284`.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/152962
2+
3+
//@ revisions: current next
4+
//@ ignore-compare-mode-next-solver (explicit revisions)
5+
//@[next] compile-flags: -Znext-solver
6+
//@ compile-flags: -Zvalidate-mir
7+
8+
#![feature(min_generic_const_args)]
9+
#![expect(incomplete_features)]
10+
11+
struct Struct;
12+
13+
impl Struct {
14+
type const N: usize = "this isn't a usize";
15+
//~^ ERROR the constant `"this isn't a usize"` is not of type `usize`
16+
}
17+
18+
fn f() -> [u8; const { Struct::N }] {}
19+
//~^ ERROR mismatched types [E0308]
20+
//[next]~| ERROR type annotations needed
21+
22+
fn main() {}

0 commit comments

Comments
 (0)