From 24afa42a90eb035e24e5dcffbc538fb96277e3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 23 May 2024 19:18:07 +0200 Subject: [PATCH 1/2] Properly deal with missing/placeholder types inside GACs --- compiler/rustc_hir_typeck/src/lib.rs | 13 +++++--- .../assoc-const-missing-type.rs | 17 ++++++++++ .../assoc-const-missing-type.stderr | 32 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 tests/ui/generic-const-items/assoc-const-missing-type.rs create mode 100644 tests/ui/generic-const-items/assoc-const-missing-type.stderr diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b9a99fbec3cd8..4f35acaa44755 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -235,11 +235,16 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti if let Some(item) = tcx.opt_associated_item(def_id.into()) && let ty::AssocKind::Const = item.kind && let ty::ImplContainer = item.container - && let Some(trait_item) = item.trait_item_def_id + && let Some(trait_item_def_id) = item.trait_item_def_id { - let args = - tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; - Some(tcx.type_of(trait_item).instantiate(tcx, args)) + let impl_def_id = item.container_id(tcx); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); + let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( + tcx, + impl_def_id, + impl_trait_ref.args, + ); + Some(tcx.type_of(trait_item_def_id).instantiate(tcx, args)) } else { Some(fcx.next_ty_var(span)) } diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs new file mode 100644 index 0000000000000..80f282ea134dc --- /dev/null +++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs @@ -0,0 +1,17 @@ +// Ensure that we properly deal with missing/placeholder types inside GACs. +// issue: rust-lang/rust#124833 +#![feature(generic_const_items)] +#![allow(incomplete_features)] + +trait Trait { + const K: T; +} + +impl Trait for () { + const K = (); + //~^ ERROR missing type for `const` item + //~| ERROR mismatched types + //~| ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr new file mode 100644 index 0000000000000..158e9a068f657 --- /dev/null +++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr @@ -0,0 +1,32 @@ +error[E0308]: mismatched types + --> $DIR/assoc-const-missing-type.rs:11:18 + | +LL | const K = (); + | - ^^ expected type parameter `T`, found `()` + | | + | expected this type parameter + | + = note: expected type parameter `T` + found unit type `()` + +error: missing type for `const` item + --> $DIR/assoc-const-missing-type.rs:11:15 + | +LL | const K = (); + | ^ help: provide a type for the associated constant: `()` + +error[E0308]: mismatched types + --> $DIR/assoc-const-missing-type.rs:11:18 + | +LL | const K = (); + | - ^^ expected type parameter `T`, found `()` + | | + | expected this type parameter + | + = note: expected type parameter `T` + found unit type `()` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From 39d9b840bbd2ed663241f4800f4d07b7950df46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 23 May 2024 20:05:28 +0200 Subject: [PATCH 2/2] Handle trait/impl GAC mismatches when inferring missing/placeholder types --- compiler/rustc_hir_typeck/src/lib.rs | 3 ++- tests/crashes/124833.rs | 10 ------- .../assoc-const-missing-type.rs | 4 +++ .../assoc-const-missing-type.stderr | 26 +++++++++++++++---- 4 files changed, 27 insertions(+), 16 deletions(-) delete mode 100644 tests/crashes/124833.rs diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 4f35acaa44755..86fe2756b59a0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -244,7 +244,8 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti impl_def_id, impl_trait_ref.args, ); - Some(tcx.type_of(trait_item_def_id).instantiate(tcx, args)) + tcx.check_args_compatible(trait_item_def_id, args) + .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args)) } else { Some(fcx.next_ty_var(span)) } diff --git a/tests/crashes/124833.rs b/tests/crashes/124833.rs deleted file mode 100644 index f1c4847b544a5..0000000000000 --- a/tests/crashes/124833.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: rust-lang/rust#124833 -#![feature(generic_const_items)] - -trait Trait { - const C<'a>: &'a str; -} - -impl Trait for () { - const C<'a>: = "C"; -} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs index 80f282ea134dc..93160f0b5758d 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.rs +++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs @@ -5,6 +5,7 @@ trait Trait { const K: T; + const Q<'a>: &'a str; } impl Trait for () { @@ -12,6 +13,9 @@ impl Trait for () { //~^ ERROR missing type for `const` item //~| ERROR mismatched types //~| ERROR mismatched types + const Q = ""; + //~^ ERROR missing type for `const` item + //~| ERROR lifetime parameters or bounds on const `Q` do not match the trait declaration } fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr index 158e9a068f657..6f35c0958d45c 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr +++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/assoc-const-missing-type.rs:11:18 + --> $DIR/assoc-const-missing-type.rs:12:18 | LL | const K = (); | - ^^ expected type parameter `T`, found `()` @@ -10,13 +10,28 @@ LL | const K = (); found unit type `()` error: missing type for `const` item - --> $DIR/assoc-const-missing-type.rs:11:15 + --> $DIR/assoc-const-missing-type.rs:12:15 | LL | const K = (); | ^ help: provide a type for the associated constant: `()` +error[E0195]: lifetime parameters or bounds on const `Q` do not match the trait declaration + --> $DIR/assoc-const-missing-type.rs:16:12 + | +LL | const Q<'a>: &'a str; + | ---- lifetimes in impl do not match this const in trait +... +LL | const Q = ""; + | ^ lifetimes do not match const in trait + +error: missing type for `const` item + --> $DIR/assoc-const-missing-type.rs:16:12 + | +LL | const Q = ""; + | ^ help: provide a type for the associated constant: `: &str` + error[E0308]: mismatched types - --> $DIR/assoc-const-missing-type.rs:11:18 + --> $DIR/assoc-const-missing-type.rs:12:18 | LL | const K = (); | - ^^ expected type parameter `T`, found `()` @@ -27,6 +42,7 @@ LL | const K = (); found unit type `()` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0195, E0308. +For more information about an error, try `rustc --explain E0195`.