Skip to content

mGCA: Add associated const type check#152146

Draft
zedddie wants to merge 1 commit intorust-lang:mainfrom
zedddie:mgca-improve-const-bindings-wfck
Draft

mGCA: Add associated const type check#152146
zedddie wants to merge 1 commit intorust-lang:mainfrom
zedddie:mgca-improve-const-bindings-wfck

Conversation

@zedddie
Copy link
Contributor

@zedddie zedddie commented Feb 5, 2026

#151642

r? BoxyUwU

I didn't bless tests just yet as it only fixes the dyn arm

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 5, 2026
@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-20-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
test [ui] tests/ui/asm/aarch64/type-check-2-2.rs ... ok
test [ui] tests/ui/asm/aarch64/ttbr0_el2.rs ... ok
test [ui] tests/ui/asm/aarch64/type-check-3.rs ... ok
test [ui] tests/ui/asm/aarch64/sym.rs ... ok
test [ui] tests/ui/asm/aarch64v8r.rs#hf ... ok
test [ui] tests/ui/asm/aarch64/type-f16.rs ... ok
test [ui] tests/ui/asm/aarch64v8r.rs#sf ... ok
test [ui] tests/ui/asm/aarch64v8r.rs#r82 ... ok
test [ui] tests/ui/asm/asm-with-nested-closure.rs ... ok
test [ui] tests/ui/asm/binary_asm_labels.rs ... ignored, only executed when the architecture is x86_64
test [ui] tests/ui/asm/bad-template.rs#aarch64 ... ok
test [ui] tests/ui/asm/arm-low-dreg.rs ... ok
test [ui] tests/ui/asm/cfg.rs#reva ... ignored, only executed when the architecture is x86_64
---
test [ui] tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs#fat2 ... ok
test [ui] tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs#fat3 ... ok
test [ui] tests/ui/extern/issue-80074.rs ... ok
test [ui] tests/ui/extern/issue-95829.rs ... ok
test [ui] tests/ui/extern/lgamma-linkage.rs ... ok
test [ui] tests/ui/extern/no-mangle-associated-fn.rs ... ok
test [ui] tests/ui/extern/not-in-block.rs ... ok
test [ui] tests/ui/extern/unsized-extern-derefmove.rs ... ok
test [ui] tests/ui/extern/windows-tcb-trash-13259.rs ... ok
test [ui] tests/ui/feature-gates/allow-features-empty.rs ... ok
---
test [ui] tests/ui/imports/ambiguous-9.rs ... ok
test [ui] tests/ui/imports/ambiguous-import-visibility-module.rs ... ok
test [ui] tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs ... ok
test [ui] tests/ui/imports/ambiguous-8.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-globvsglob.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-pick-core.rs ... ok
test [ui] tests/ui/imports/ambiguous-panic-pick-std.rs ... ok
---
22 LL | impl A for () {
23    | ^^^^^^^^^^^^^
24 
- error: aborting due to 2 previous errors
+ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
+   --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:12
+    |
+ LL |     let _: dyn A<Ty = i32, CT = 0>;
+    |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `FreshTy(0)`
+    |
+ help: the trait `A` is implemented for `()`
+   --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
+    |
+ LL | impl A for () {
---
27 For more information about this error, try `rustc --explain E0277`.
28 

Note: some mismatched output was normalized before being compared
-   --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:12
-   --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
+ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
+   --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:12
+    |
+ LL |     let _: dyn A<Ty = i32, CT = 0>;
+    |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `FreshTy(0)`
+    |
+ help: the trait `A` is implemented for `()`
+   --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
+    |
+ LL | impl A for () {
---
To only update this specific test, also pass `--test-args const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
##[error]  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:33
   |
LL |     let _: dyn A<Ty = i32, CT = 0>;
   |                                 ^ the trait `A` is not implemented for `FreshTy(0)`
   |
help: the trait `A` is implemented for `()`
  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
   |
LL | impl A for () {
   | ^^^^^^^^^^^^^

error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
##[error]  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:29:34
   |
LL |     let _: &dyn A<Ty = i32, CT = 0> = &();
   |                                  ^ the trait `A` is not implemented for `FreshTy(0)`
   |
help: the trait `A` is implemented for `()`
  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
   |
LL | impl A for () {
   | ^^^^^^^^^^^^^

error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
##[error]  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:12
   |
LL |     let _: dyn A<Ty = i32, CT = 0>;
   |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `FreshTy(0)`
   |
help: the trait `A` is implemented for `()`
  --> /checkout/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1
   |
LL | impl A for () {
---
---- [ui] tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/const-generics/associated-const-bindings/wf-mismatch-2" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error: the constant `N` is not of type `bool`
##[error]  --> /checkout/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs:10:12
   |
LL |     let _: dyn Trait<CT = { N }>; // FIXME: this should yield a type mismatch (`bool` v `i32`)
   |            ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32`

error: aborting due to 1 previous error
------------------------------------------

---- [ui] tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs stdout end ----
---- [ui] tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/const-generics/associated-const-bindings/wf-mismatch-3" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error: the constant `0` is not of type `bool`
##[error]  --> /checkout/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs:12:17
   |
LL | fn f() { let _: dyn Trait<CT = { <() as Bound>::N }>; } // FIXME
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32`

error: aborting due to 1 previous error
------------------------------------------

---- [ui] tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs stdout end ----


for projection in data.projection_bounds() {
let pred_binder = projection
.with_self_ty(tcx, tcx.types.trait_object_dummy_self)
Copy link
Member

@BoxyUwU BoxyUwU Feb 5, 2026

Choose a reason for hiding this comment

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

Suggested change
.with_self_ty(tcx, tcx.types.trait_object_dummy_self)
.with_self_ty(tcx, t)

I expect using trait_object_dummy_self might lead to code on the error-path crashing so we should use the "actual" self type. It also might just lead to weird diagnostics, such as Infer(FreshTy(0)) appearing in user facing text which we don't want.

Though eventually we'll also support assocaited constants such as const ASSOC: <Self as Other>::Assoc at which point Self will need to be a real type that implements Trait so that we can figure out the type of Assoc.

What's going on here is that we have the type dyn Trait<T, ASSOC = 10> (for example), and we want to construct [dyn Trait<T, ASSOC = 10>, T] as a list of generic arguments to <T as Trait<U>>::ASSOC for when we look at the type of ASSOC.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh I really missed we have the type in scope and can use it -_-, then it will be perfect here


trait Trait { #[type_const] const CT: bool; }

// FIXME: this should yield a type mismatch (`bool` v `i32`)
Copy link
Member

Choose a reason for hiding this comment

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

This will get fixed once you add wf checks for T: Trait<ASSOC = N> where clauses.

You can do this by adding fairly similar logic to what you've already done, but in rustc_hir_analysis/src/check/wfcheck.rs in the check_where_clause function

You should be able to similarly iterate over all of the predicates and filter to only those that are associated const bindings

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 5, 2026

very nice :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants