about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-06-14 18:10:30 +0200
committerGitHub <noreply@github.com>2023-06-14 18:10:30 +0200
commitc1b4d075a2e5304437769bc3847ebb1d5db2c3fa (patch)
tree161f24e23d3f258ee5919a077ac174b8ad9c2f76
parent38ed4e5a5cf1820ed76bcba235b70dcb29f8118d (diff)
parent2b40268f8bed4ba1d916a216a4431bb2ec7b2d41 (diff)
downloadrust-c1b4d075a2e5304437769bc3847ebb1d5db2c3fa.tar.gz
rust-c1b4d075a2e5304437769bc3847ebb1d5db2c3fa.zip
Rollup merge of #112506 - compiler-errors:const-infer-ice, r=b-naber
Properly check associated consts for infer placeholders

We only reported an error if it was in a "suggestable" position (according to `is_suggestable_infer_ty`) -- this isn't correct for infer tys that can show up in other places in the constant's type, like behind a dyn trait.

fixes #112491
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs16
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs10
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr9
-rw-r--r--tests/ui/const-generics/generic_arg_infer/in-signature.rs6
-rw-r--r--tests/ui/const-generics/generic_arg_infer/in-signature.stderr6
-rw-r--r--tests/ui/typeck/type-placeholder-fn-in-const.rs3
-rw-r--r--tests/ui/typeck/type-placeholder-fn-in-const.stderr10
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs8
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr8
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item_help.rs4
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item_help.stderr4
12 files changed, 77 insertions, 34 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index c7b9fc9a697..8b5c1791fc1 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -666,17 +666,15 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
             tcx.ensure().fn_sig(def_id);
         }
 
-        hir::TraitItemKind::Const(.., Some(_)) => {
+        hir::TraitItemKind::Const(ty, body_id) => {
             tcx.ensure().type_of(def_id);
-        }
-
-        hir::TraitItemKind::Const(hir_ty, _) => {
-            tcx.ensure().type_of(def_id);
-            // Account for `const C: _;`.
-            let mut visitor = HirPlaceholderCollector::default();
-            visitor.visit_trait_item(trait_item);
-            if !tcx.sess.diagnostic().has_stashed_diagnostic(hir_ty.span, StashKey::ItemNoType) {
-                placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
+            if !tcx.sess.diagnostic().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
+                && !(is_suggestable_infer_ty(ty) && body_id.is_some())
+            {
+                // Account for `const C: _;`.
+                let mut visitor = HirPlaceholderCollector::default();
+                visitor.visit_trait_item(trait_item);
+                placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant");
             }
         }
 
@@ -721,7 +719,14 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
 
             placeholder_type_error(tcx, None, visitor.0, false, None, "associated type");
         }
-        hir::ImplItemKind::Const(..) => {}
+        hir::ImplItemKind::Const(ty, _) => {
+            // Account for `const T: _ = ..;`
+            if !is_suggestable_infer_ty(ty) {
+                let mut visitor = HirPlaceholderCollector::default();
+                visitor.visit_impl_item(impl_item);
+                placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant");
+            }
+        }
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c2b837fcfa6..318d0d0c223 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -341,7 +341,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
                 .and_then(|body_id| {
                     is_suggestable_infer_ty(ty).then(|| {
                         infer_placeholder_type(
-                            tcx, def_id, body_id, ty.span, item.ident, "constant",
+                            tcx,
+                            def_id,
+                            body_id,
+                            ty.span,
+                            item.ident,
+                            "associated constant",
                         )
                     })
                 })
@@ -359,7 +364,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             }
             ImplItemKind::Const(ty, body_id) => {
                 if is_suggestable_infer_ty(ty) {
-                    infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
+                    infer_placeholder_type(
+                        tcx,
+                        def_id,
+                        body_id,
+                        ty.span,
+                        item.ident,
+                        "associated constant",
+                    )
                 } else {
                     icx.to_ty(ty)
                 }
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
new file mode 100644
index 00000000000..40896c32e11
--- /dev/null
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
@@ -0,0 +1,10 @@
+trait Trait {
+    const ASSOC: i32;
+}
+
+impl Trait for () {
+    const ASSOC: &dyn Fn(_) = 1i32;
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
new file mode 100644
index 00000000000..993a08faba9
--- /dev/null
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
@@ -0,0 +1,9 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26
+   |
+LL |     const ASSOC: &dyn Fn(_) = 1i32;
+   |                          ^ not allowed in type signatures
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.rs b/tests/ui/const-generics/generic_arg_infer/in-signature.rs
index 1f60b224241..cd852a26943 100644
--- a/tests/ui/const-generics/generic_arg_infer/in-signature.rs
+++ b/tests/ui/const-generics/generic_arg_infer/in-signature.rs
@@ -33,15 +33,15 @@ static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
 trait ArrAssocConst {
     const ARR: [u8; _];
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 trait TyAssocConst {
     const ARR: Bar<i32, _>;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 trait TyAssocConstMixed {
     const ARR: Bar<_, _>;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 
 trait AssocTy {
diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
index 52d1b29f932..b32018a6a2d 100644
--- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
@@ -74,19 +74,19 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
    |                         not allowed in type signatures
    |                         help: replace with the correct type: `Bar<i32, 3>`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/in-signature.rs:35:21
    |
 LL |     const ARR: [u8; _];
    |                     ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/in-signature.rs:39:25
    |
 LL |     const ARR: Bar<i32, _>;
    |                         ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/in-signature.rs:43:20
    |
 LL |     const ARR: Bar<_, _>;
diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.rs b/tests/ui/typeck/type-placeholder-fn-in-const.rs
index ab2e2d8c53a..bbb95a5798a 100644
--- a/tests/ui/typeck/type-placeholder-fn-in-const.rs
+++ b/tests/ui/typeck/type-placeholder-fn-in-const.rs
@@ -3,12 +3,13 @@ struct MyStruct;
 trait Test {
     const TEST: fn() -> _;
     //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121]
-    //~| ERROR: the placeholder `_` is not allowed within types on item signatures for constants [E0121]
+    //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121]
 }
 
 impl Test for MyStruct {
     const TEST: fn() -> _ = 42;
     //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121]
+    //~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121]
 }
 
 fn main() {}
diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.stderr b/tests/ui/typeck/type-placeholder-fn-in-const.stderr
index e7b2e554a8d..302359d2500 100644
--- a/tests/ui/typeck/type-placeholder-fn-in-const.stderr
+++ b/tests/ui/typeck/type-placeholder-fn-in-const.stderr
@@ -4,7 +4,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     const TEST: fn() -> _;
    |                         ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/type-placeholder-fn-in-const.rs:4:25
    |
 LL |     const TEST: fn() -> _;
@@ -16,6 +16,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     const TEST: fn() -> _ = 42;
    |                         ^ not allowed in type signatures
 
-error: aborting due to 3 previous errors
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/type-placeholder-fn-in-const.rs:10:25
+   |
+LL |     const TEST: fn() -> _ = 42;
+   |                         ^ not allowed in type signatures
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 46aed0f603e..4eba14f5a93 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -190,9 +190,9 @@ trait Qux {
     type B = _;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
     const C: _;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
     const D: _ = 42;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
     // type E: _; // FIXME: make the parser propagate the existence of `B`
     type F: std::ops::Fn(_);
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
@@ -203,10 +203,10 @@ impl Qux for Struct {
     type B = _;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
     const C: _;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
     //~| ERROR associated constant in `impl` without body
     const D: _ = 42;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 
 fn map<T>(_: fn() -> Option<&'static T>) -> Option<T> {
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index bc02547c65e..0c5e7e3cecb 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -525,13 +525,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item.rs:192:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item.rs:194:14
    |
 LL |     const D: _ = 42;
@@ -642,13 +642,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item.rs:205:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item.rs:208:14
    |
 LL |     const D: _ = 42;
diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.rs b/tests/ui/typeck/typeck_type_placeholder_item_help.rs
index c459d8c3cdc..914f8a2b28b 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item_help.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item_help.rs
@@ -16,14 +16,14 @@ const TEST4: fn() -> _ = 42;
 
 trait Test5 {
     const TEST5: _ = 42;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 
 struct Test6;
 
 impl Test6 {
     const TEST6: _ = 13;
-    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
 }
 
 pub fn main() {
diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
index 07a5dbd93c7..ed6f4088019 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
@@ -37,7 +37,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL | const TEST4: fn() -> _ = 42;
    |                      ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item_help.rs:18:18
    |
 LL |     const TEST5: _ = 42;
@@ -46,7 +46,7 @@ LL |     const TEST5: _ = 42;
    |                  not allowed in type signatures
    |                  help: replace with the correct type: `i32`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/typeck_type_placeholder_item_help.rs:25:18
    |
 LL |     const TEST6: _ = 13;