about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-02 18:18:19 +0000
committerMichael Goulet <michael@errs.io>2025-01-02 23:39:16 +0000
commitc529fe0475e7c8161e950c9dc2d1409073593750 (patch)
tree16a1a548c9dd6529244e1e053dc9a48f89a16a14
parentc5d4996404fe7ed37a94d83d7b632ed6a566d2ac (diff)
downloadrust-c529fe0475e7c8161e950c9dc2d1409073593750.tar.gz
rust-c529fe0475e7c8161e950c9dc2d1409073593750.zip
Remove diagnostic_only_typeck and fix placeholder suggestion for const/static
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs43
-rw-r--r--compiler/rustc_middle/src/query/mod.rs3
-rw-r--r--tests/ui/const-generics/generic_arg_infer/in-signature.stderr10
-rw-r--r--tests/ui/consts/issue-104768.rs1
-rw-r--r--tests/ui/consts/issue-104768.stderr18
-rw-r--r--tests/ui/generic-const-items/assoc-const-missing-type.rs1
-rw-r--r--tests/ui/generic-const-items/assoc-const-missing-type.stderr18
-rw-r--r--tests/ui/parser/issues/issue-89574.rs1
-rw-r--r--tests/ui/parser/issues/issue-89574.stderr10
-rw-r--r--tests/ui/typeck/issue-79040.rs6
-rw-r--r--tests/ui/typeck/issue-79040.stderr12
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs1
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr41
14 files changed, 85 insertions, 82 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c0526903e88..f51018f5c3f 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -412,7 +412,7 @@ fn infer_placeholder_type<'tcx>(
     kind: &'static str,
 ) -> Ty<'tcx> {
     let tcx = cx.tcx();
-    let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
+    let ty = tcx.typeck(def_id).node_type(body_id.hir_id);
 
     // If this came from a free `const` or `static mut?` item,
     // then the user may have written e.g. `const A = 42;`.
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index b24aa0e4693..5a0a855147d 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -87,21 +87,7 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef
 }
 
 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
-    let fallback = move || tcx.type_of(def_id.to_def_id()).instantiate_identity();
-    typeck_with_fallback(tcx, def_id, fallback, None)
-}
-
-/// Used only to get `TypeckResults` for type inference during error recovery.
-/// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
-fn diagnostic_only_typeck<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    def_id: LocalDefId,
-) -> &'tcx ty::TypeckResults<'tcx> {
-    let fallback = move || {
-        let span = tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
-        Ty::new_error_with_message(tcx, span, "diagnostic only typeck table used")
-    };
-    typeck_with_fallback(tcx, def_id, fallback, None)
+    typeck_with_fallback(tcx, def_id, None)
 }
 
 /// Same as `typeck` but `inspect` is invoked on evaluation of each root obligation.
@@ -113,15 +99,13 @@ pub fn inspect_typeck<'tcx>(
     def_id: LocalDefId,
     inspect: ObligationInspector<'tcx>,
 ) -> &'tcx ty::TypeckResults<'tcx> {
-    let fallback = move || tcx.type_of(def_id.to_def_id()).instantiate_identity();
-    typeck_with_fallback(tcx, def_id, fallback, Some(inspect))
+    typeck_with_fallback(tcx, def_id, Some(inspect))
 }
 
-#[instrument(level = "debug", skip(tcx, fallback, inspector), ret)]
+#[instrument(level = "debug", skip(tcx, inspector), ret)]
 fn typeck_with_fallback<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
-    fallback: impl Fn() -> Ty<'tcx> + 'tcx,
     inspector: Option<ObligationInspector<'tcx>>,
 ) -> &'tcx ty::TypeckResults<'tcx> {
     // Closures' typeck results come from their outermost function,
@@ -151,6 +135,10 @@ fn typeck_with_fallback<'tcx>(
 
     if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() {
         let fn_sig = if decl.output.is_suggestable_infer_ty().is_some() {
+            // In the case that we're recovering `fn() -> W<_>` or some other return
+            // type that has an infer in it, lower the type directly so that it'll
+            // be correctly filled with infer. We'll use this inference to provide
+            // a suggestion later on.
             fcx.lowerer().lower_fn_ty(id, header.safety, header.abi, decl, None, None)
         } else {
             tcx.fn_sig(def_id).instantiate_identity()
@@ -164,8 +152,19 @@ fn typeck_with_fallback<'tcx>(
 
         check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
     } else {
-        let expected_type = infer_type_if_missing(&fcx, node);
-        let expected_type = expected_type.unwrap_or_else(fallback);
+        let expected_type = if let Some(infer_ty) = infer_type_if_missing(&fcx, node) {
+            infer_ty
+        } else if let Some(ty) = node.ty()
+            && ty.is_suggestable_infer_ty()
+        {
+            // In the case that we're recovering `const X: [T; _]` or some other
+            // type that has an infer in it, lower the type directly so that it'll
+            // be correctly filled with infer. We'll use this inference to provide
+            // a suggestion later on.
+            fcx.lowerer().lower_ty(ty)
+        } else {
+            tcx.type_of(def_id).instantiate_identity()
+        };
 
         let expected_type = fcx.normalize(body.value.span, expected_type);
 
@@ -506,5 +505,5 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
 
 pub fn provide(providers: &mut Providers) {
     method::provide(providers);
-    *providers = Providers { typeck, diagnostic_only_typeck, used_trait_imports, ..*providers };
+    *providers = Providers { typeck, used_trait_imports, ..*providers };
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 7e7b602c560..b6934495e44 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1100,9 +1100,6 @@ rustc_queries! {
         desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) }
         cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) }
     }
-    query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
-        desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) }
-    }
 
     query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> {
         desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) }
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 fcac95732d1..afe6f5eb67e 100644
--- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
@@ -30,13 +30,19 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/in-signature.rs:22:15
    |
 LL | const ARR_CT: [u8; _] = [0; 3];
-   |               ^^^^^^^ not allowed in type signatures
+   |               ^^^^^^^
+   |               |
+   |               not allowed in type signatures
+   |               help: replace with the correct type: `[u8; 3]`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
   --> $DIR/in-signature.rs:24:20
    |
 LL | static ARR_STATIC: [u8; _] = [0; 3];
-   |                    ^^^^^^^ not allowed in type signatures
+   |                    ^^^^^^^
+   |                    |
+   |                    not allowed in type signatures
+   |                    help: replace with the correct type: `[u8; 3]`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/in-signature.rs:26:14
diff --git a/tests/ui/consts/issue-104768.rs b/tests/ui/consts/issue-104768.rs
index 3192daafa0b..52a8070be4e 100644
--- a/tests/ui/consts/issue-104768.rs
+++ b/tests/ui/consts/issue-104768.rs
@@ -1,4 +1,5 @@
 const A: &_ = 0_u32;
 //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for constants
+//~| ERROR: mismatched types
 
 fn main() {}
diff --git a/tests/ui/consts/issue-104768.stderr b/tests/ui/consts/issue-104768.stderr
index 8a4a41e4d68..b5f22763e28 100644
--- a/tests/ui/consts/issue-104768.stderr
+++ b/tests/ui/consts/issue-104768.stderr
@@ -1,3 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-104768.rs:1:15
+   |
+LL | const A: &_ = 0_u32;
+   |               ^^^^^ expected `&_`, found `u32`
+   |
+   = note: expected reference `&'static _`
+                   found type `u32`
+help: consider borrowing here
+   |
+LL | const A: &_ = &0_u32;
+   |               +
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/issue-104768.rs:1:10
    |
@@ -7,6 +20,7 @@ LL | const A: &_ = 0_u32;
    |          not allowed in type signatures
    |          help: replace with the correct type: `u32`
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0121`.
+Some errors have detailed explanations: E0121, E0308.
+For more information about an error, try `rustc --explain E0121`.
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 93160f0b575..0c94a4262ef 100644
--- a/tests/ui/generic-const-items/assoc-const-missing-type.rs
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs
@@ -12,7 +12,6 @@ impl Trait for () {
     const K<T> = ();
     //~^ 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
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 6f35c0958d4..5af119dffa7 100644
--- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr
@@ -16,7 +16,7 @@ LL |     const K<T> = ();
    |               ^ 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
+  --> $DIR/assoc-const-missing-type.rs:15:12
    |
 LL |     const Q<'a>: &'a str;
    |            ---- lifetimes in impl do not match this const in trait
@@ -25,24 +25,12 @@ LL |     const Q = "";
    |            ^ lifetimes do not match const in trait
 
 error: missing type for `const` item
-  --> $DIR/assoc-const-missing-type.rs:16:12
+  --> $DIR/assoc-const-missing-type.rs:15:12
    |
 LL |     const Q = "";
    |            ^ help: provide a type for the associated constant: `: &str`
 
-error[E0308]: mismatched types
-  --> $DIR/assoc-const-missing-type.rs:12:18
-   |
-LL |     const K<T> = ();
-   |             -    ^^ 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 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0195, E0308.
 For more information about an error, try `rustc --explain E0195`.
diff --git a/tests/ui/parser/issues/issue-89574.rs b/tests/ui/parser/issues/issue-89574.rs
index bafb0ce5e66..276abfe7110 100644
--- a/tests/ui/parser/issues/issue-89574.rs
+++ b/tests/ui/parser/issues/issue-89574.rs
@@ -2,5 +2,4 @@ fn main() {
     const EMPTY_ARRAY = [];
     //~^ missing type for `const` item
     //~| ERROR type annotations needed
-    //~| ERROR type annotations needed
 }
diff --git a/tests/ui/parser/issues/issue-89574.stderr b/tests/ui/parser/issues/issue-89574.stderr
index aa5e66b18a9..f40f5aded8e 100644
--- a/tests/ui/parser/issues/issue-89574.stderr
+++ b/tests/ui/parser/issues/issue-89574.stderr
@@ -15,14 +15,6 @@ help: provide a type for the item
 LL |     const EMPTY_ARRAY: <type> = [];
    |                      ++++++++
 
-error[E0282]: type annotations needed
-  --> $DIR/issue-89574.rs:2:25
-   |
-LL |     const EMPTY_ARRAY = [];
-   |                         ^^ cannot infer type
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/typeck/issue-79040.rs b/tests/ui/typeck/issue-79040.rs
index 03e00820756..f8e38e7867d 100644
--- a/tests/ui/typeck/issue-79040.rs
+++ b/tests/ui/typeck/issue-79040.rs
@@ -1,6 +1,6 @@
 fn main() {
-    const FOO = "hello" + 1; //~ ERROR cannot add `{integer}` to `&str`
-    //~^ missing type for `const` item
-    //~| ERROR cannot add `{integer}` to `&str`
+    const FOO = "hello" + 1;
+    //~^ ERROR cannot add `{integer}` to `&str`
+    //~| missing type for `const` item
     println!("{}", FOO);
 }
diff --git a/tests/ui/typeck/issue-79040.stderr b/tests/ui/typeck/issue-79040.stderr
index 39636db85a7..4ab8df8f6c9 100644
--- a/tests/ui/typeck/issue-79040.stderr
+++ b/tests/ui/typeck/issue-79040.stderr
@@ -17,16 +17,6 @@ help: provide a type for the item
 LL |     const FOO: <type> = "hello" + 1;
    |              ++++++++
 
-error[E0369]: cannot add `{integer}` to `&str`
-  --> $DIR/issue-79040.rs:2:25
-   |
-LL |     const FOO = "hello" + 1;
-   |                 ------- ^ - {integer}
-   |                 |
-   |                 &str
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 437a1aed403..9f1bfd7909e 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -221,6 +221,7 @@ fn value() -> Option<&'static _> {
 
 const _: Option<_> = map(value);
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+//~| ERROR cannot call non-const function `map::<u8>` in constants
 
 fn evens_squared(n: usize) -> _ {
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index e62ebae5fd2..30cdd0e72a7 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -85,7 +85,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:19:15
    |
 LL | static TEST5: (_, _) = (1, 2);
-   |               ^^^^^^ not allowed in type signatures
+   |               ^^^^^^
+   |               |
+   |               not allowed in type signatures
+   |               help: replace with the correct type: `(i32, i32)`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/typeck_type_placeholder_item.rs:22:13
@@ -229,7 +232,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:77:15
    |
 LL |     static C: Option<_> = Some(42);
-   |               ^^^^^^^^^ not allowed in type signatures
+   |               ^^^^^^^^^
+   |               |
+   |               not allowed in type signatures
+   |               help: replace with the correct type: `Option<i32>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:79:21
@@ -272,7 +278,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:91:22
    |
 LL |     static FN_TEST5: (_, _) = (1, 2);
-   |                      ^^^^^^ not allowed in type signatures
+   |                      ^^^^^^
+   |                      |
+   |                      not allowed in type signatures
+   |                      help: replace with the correct type: `(i32, i32)`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/typeck_type_placeholder_item.rs:94:20
@@ -578,7 +587,7 @@ LL | const _: Option<_> = map(value);
    |          help: replace with the correct type: `Option<u8>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/typeck_type_placeholder_item.rs:225:31
+  --> $DIR/typeck_type_placeholder_item.rs:226:31
    |
 LL | fn evens_squared(n: usize) -> _ {
    |                               ^
@@ -587,13 +596,13 @@ LL | fn evens_squared(n: usize) -> _ {
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:230:10
+  --> $DIR/typeck_type_placeholder_item.rs:231:10
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |          ^ not allowed in type signatures
    |
-note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:230:29}>, {closure@typeck_type_placeholder_item.rs:230:49}>` cannot be named
-  --> $DIR/typeck_type_placeholder_item.rs:230:14
+note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:231:29}>, {closure@typeck_type_placeholder_item.rs:231:49}>` cannot be named
+  --> $DIR/typeck_type_placeholder_item.rs:231:14
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -668,23 +677,31 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     type F: std::ops::Fn(_);
    |                          ^ not allowed in type signatures
 
-error[E0015]: cannot call non-const method `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}>` in constants
-  --> $DIR/typeck_type_placeholder_item.rs:230:22
+error[E0015]: cannot call non-const function `map::<u8>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:222:22
+   |
+LL | const _: Option<_> = map(value);
+   |                      ^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+
+error[E0015]: cannot call non-const method `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:231:22
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |                      ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:230:49: 230:52}>` in constants
-  --> $DIR/typeck_type_placeholder_item.rs:230:45
+error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:231:49: 231:52}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:231:45
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |                                             ^^^^^^^^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 74 previous errors
+error: aborting due to 75 previous errors
 
 Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403.
 For more information about an error, try `rustc --explain E0015`.