about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-02 18:49:43 +0000
committerMichael Goulet <michael@errs.io>2025-01-02 23:39:16 +0000
commit6885ff4a7b40f7550fd27c405c7f4ea3768bddb6 (patch)
tree086afc694f78ff9067d6937ea7c3b376b1219f4a
parentb85a91fc598117ab23eb5dd294ed3371bc7081d9 (diff)
downloadrust-6885ff4a7b40f7550fd27c405c7f4ea3768bddb6.tar.gz
rust-6885ff4a7b40f7550fd27c405c7f4ea3768bddb6.zip
Unconditionally lower generic_arg_infer
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs17
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs1
-rw-r--r--tests/ui/array-slice-vec/suggest-array-length.fixed25
-rw-r--r--tests/ui/array-slice-vec/suggest-array-length.rs25
-rw-r--r--tests/ui/array-slice-vec/suggest-array-length.stderr93
-rw-r--r--tests/ui/async-await/issues/issue-95307.rs4
-rw-r--r--tests/ui/async-await/issues/issue-95307.stderr12
-rw-r--r--tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr18
-rw-r--r--tests/ui/feature-gates/feature-gate-generic_arg_infer.rs2
10 files changed, 89 insertions, 117 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 46e91636cfb..fe2d5a594f3 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2031,11 +2031,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
         match c.value.kind {
             ExprKind::Underscore => {
-                if self.tcx.features().generic_arg_infer() {
-                    let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
-                    self.arena
-                        .alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
-                } else {
+                if !self.tcx.features().generic_arg_infer() {
                     feature_err(
                         &self.tcx.sess,
                         sym::generic_arg_infer,
@@ -2043,8 +2039,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         fluent_generated::ast_lowering_underscore_array_length_unstable,
                     )
                     .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
-                    self.lower_anon_const_to_const_arg(c)
                 }
+                let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
+                self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
             }
             _ => self.lower_anon_const_to_const_arg(c),
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 35a319dc5bd..76e125aebf9 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -452,6 +452,12 @@ fn infer_placeholder_type<'tcx>(
             if let Some(ty) = tcx.hir_node_by_def_id(def_id).ty() {
                 visitor.visit_ty(ty);
             }
+            // If we have just one span, let's try to steal a const `_` feature error.
+            let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.0.len() == 1 {
+                visitor.0.first().copied()
+            } else {
+                None
+            };
             // If we didn't find any infer tys, then just fallback to `span``.
             if visitor.0.is_empty() {
                 visitor.0.push(span);
@@ -473,7 +479,16 @@ fn infer_placeholder_type<'tcx>(
                     ));
                 }
             }
-            diag.emit()
+
+            if let Some(try_steal_span) = try_steal_span {
+                cx.dcx().try_steal_replace_and_emit_err(
+                    try_steal_span,
+                    StashKey::UnderscoreForArrayLengths,
+                    diag,
+                )
+            } else {
+                diag.emit()
+            }
         });
     Ty::new_error(tcx, guar)
 }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 8ba9a4bab57..1f32887ce9b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1774,7 +1774,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some((
             _,
             hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. })
-            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }),
         )) = parent_node
         else {
             return;
diff --git a/tests/ui/array-slice-vec/suggest-array-length.fixed b/tests/ui/array-slice-vec/suggest-array-length.fixed
index 29f85da56e5..2eacc2517d3 100644
--- a/tests/ui/array-slice-vec/suggest-array-length.fixed
+++ b/tests/ui/array-slice-vec/suggest-array-length.fixed
@@ -3,24 +3,21 @@
 
 fn main() {
     const Foo: [i32; 3] = [1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
     const REF_FOO: &[u8; 1] = &[1];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    static Statik: [i32; 3] = [1, 2, 3];
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
+    static REF_STATIK: &[u8; 1] = &[1];
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
     let foo: [i32; 3] = [1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let bar: [i32; 3] = [0; 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let ref_foo: &[i32; 3] = &[1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let ref_bar: &[i32; 3] = &[0; 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let multiple_ref_foo: &&[i32; 3] = &&[1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
 }
diff --git a/tests/ui/array-slice-vec/suggest-array-length.rs b/tests/ui/array-slice-vec/suggest-array-length.rs
index 82d871cf875..fb4424cfed9 100644
--- a/tests/ui/array-slice-vec/suggest-array-length.rs
+++ b/tests/ui/array-slice-vec/suggest-array-length.rs
@@ -3,24 +3,21 @@
 
 fn main() {
     const Foo: [i32; _] = [1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
     const REF_FOO: &[u8; _] = &[1];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+    static Statik: [i32; _] = [1, 2, 3];
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
+    static REF_STATIK: &[u8; _] = &[1];
+    //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
     let foo: [i32; _] = [1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let bar: [i32; _] = [0; 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let ref_foo: &[i32; _] = &[1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let ref_bar: &[i32; _] = &[0; 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
     let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
-    //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
-    //~| ERROR using `_` for array lengths is unstable
+    //~^ ERROR using `_` for array lengths is unstable
 }
diff --git a/tests/ui/array-slice-vec/suggest-array-length.stderr b/tests/ui/array-slice-vec/suggest-array-length.stderr
index fdab7ba7064..c0fc2989d5b 100644
--- a/tests/ui/array-slice-vec/suggest-array-length.stderr
+++ b/tests/ui/array-slice-vec/suggest-array-length.stderr
@@ -1,67 +1,41 @@
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:11:20
-   |
-LL |     let foo: [i32; _] = [1, 2, 3];
-   |                    ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:14:20
-   |
-LL |     let bar: [i32; _] = [0; 3];
-   |                    ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:17:25
-   |
-LL |     let ref_foo: &[i32; _] = &[1, 2, 3];
-   |                         ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:20:25
-   |
-LL |     let ref_bar: &[i32; _] = &[0; 3];
-   |                         ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:23:35
-   |
-LL |     let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
-   |                                   ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/suggest-array-length.rs:5:22
    |
 LL |     const Foo: [i32; _] = [1, 2, 3];
-   |                      ^ `_` not allowed here
+   |                ------^-
+   |                |     |
+   |                |     not allowed in type signatures
+   |                help: replace with the correct type: `[i32; 3]`
 
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/suggest-array-length.rs:8:26
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+  --> $DIR/suggest-array-length.rs:7:26
    |
 LL |     const REF_FOO: &[u8; _] = &[1];
-   |                          ^ `_` not allowed here
+   |                    ------^-
+   |                    |     |
+   |                    |     not allowed in type signatures
+   |                    help: replace with the correct type: `&[u8; 1]`
 
-error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:5:22
-   |
-LL |     const Foo: [i32; _] = [1, 2, 3];
-   |                      ^ help: consider specifying the array length: `3`
-   |
-   = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
-   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
+  --> $DIR/suggest-array-length.rs:9:26
+   |
+LL |     static Statik: [i32; _] = [1, 2, 3];
+   |                    ------^-
+   |                    |     |
+   |                    |     not allowed in type signatures
+   |                    help: replace with the correct type: `[i32; 3]`
 
-error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:8:26
-   |
-LL |     const REF_FOO: &[u8; _] = &[1];
-   |                          ^ help: consider specifying the array length: `1`
-   |
-   = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
-   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
+  --> $DIR/suggest-array-length.rs:11:30
+   |
+LL |     static REF_STATIK: &[u8; _] = &[1];
+   |                        ------^-
+   |                        |     |
+   |                        |     not allowed in type signatures
+   |                        help: replace with the correct type: `&[u8; 1]`
 
 error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:11:20
+  --> $DIR/suggest-array-length.rs:13:20
    |
 LL |     let foo: [i32; _] = [1, 2, 3];
    |                    ^ help: consider specifying the array length: `3`
@@ -71,7 +45,7 @@ LL |     let foo: [i32; _] = [1, 2, 3];
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:14:20
+  --> $DIR/suggest-array-length.rs:15:20
    |
 LL |     let bar: [i32; _] = [0; 3];
    |                    ^ help: consider specifying the array length: `3`
@@ -91,7 +65,7 @@ LL |     let ref_foo: &[i32; _] = &[1, 2, 3];
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:20:25
+  --> $DIR/suggest-array-length.rs:19:25
    |
 LL |     let ref_bar: &[i32; _] = &[0; 3];
    |                         ^ help: consider specifying the array length: `3`
@@ -101,7 +75,7 @@ LL |     let ref_bar: &[i32; _] = &[0; 3];
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/suggest-array-length.rs:23:35
+  --> $DIR/suggest-array-length.rs:21:35
    |
 LL |     let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
    |                                   ^ help: consider specifying the array length: `3`
@@ -110,6 +84,7 @@ LL |     let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3];
    = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 14 previous errors
+error: aborting due to 9 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0121, E0658.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/async-await/issues/issue-95307.rs b/tests/ui/async-await/issues/issue-95307.rs
index 40700c610f3..27903a667fb 100644
--- a/tests/ui/async-await/issues/issue-95307.rs
+++ b/tests/ui/async-await/issues/issue-95307.rs
@@ -5,8 +5,8 @@
 
 pub trait C {
     async fn new() -> [u8; _];
-    //~^ ERROR: using `_` for array lengths is unstable
-    //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
+    //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions
+    //~| ERROR using `_` for array lengths is unstable
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/issues/issue-95307.stderr b/tests/ui/async-await/issues/issue-95307.stderr
index dd8fcd3690a..8445c3f9811 100644
--- a/tests/ui/async-await/issues/issue-95307.stderr
+++ b/tests/ui/async-await/issues/issue-95307.stderr
@@ -1,8 +1,13 @@
-error: in expressions, `_` can only be used on the left-hand side of an assignment
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/issue-95307.rs:7:28
    |
 LL |     async fn new() -> [u8; _];
-   |                            ^ `_` not allowed here
+   |                            ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     async fn new<T>() -> [u8; T];
+   |                 +++           ~
 
 error[E0658]: using `_` for array lengths is unstable
   --> $DIR/issue-95307.rs:7:28
@@ -16,4 +21,5 @@ LL |     async fn new() -> [u8; _];
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0121, E0658.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
index 97370f0489b..96fb4a53609 100644
--- a/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
+++ b/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
@@ -1,17 +1,5 @@
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/feature-gate-generic_arg_infer.rs:11:27
-   |
-LL |     let _x: [u8; 3] = [0; _];
-   |                           ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/feature-gate-generic_arg_infer.rs:14:18
-   |
-LL |     let _y: [u8; _] = [0; 3];
-   |                  ^ `_` not allowed here
-
 error[E0658]: using `_` for array lengths is unstable
-  --> $DIR/feature-gate-generic_arg_infer.rs:14:18
+  --> $DIR/feature-gate-generic_arg_infer.rs:13:18
    |
 LL |     let _y: [u8; _] = [0; 3];
    |                  ^ help: consider specifying the array length: `3`
@@ -21,7 +9,7 @@ LL |     let _y: [u8; _] = [0; 3];
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/feature-gate-generic_arg_infer.rs:20:20
+  --> $DIR/feature-gate-generic_arg_infer.rs:18:20
    |
 LL |     let _x = foo::<_>([1,2]);
    |                    ^
@@ -42,7 +30,7 @@ LL |     let _x: [u8; 3] = [0; _];
    = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0658, E0747.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs
index 0473253004a..de4b7078ea6 100644
--- a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs
+++ b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs
@@ -10,10 +10,8 @@ fn foo<const N: usize>(_: [u8; N]) -> [u8; N] {
 fn bar() {
     let _x: [u8; 3] = [0; _];
     //[normal]~^ ERROR: using `_` for array lengths is unstable
-    //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
     let _y: [u8; _] = [0; 3];
     //[normal]~^ ERROR: using `_` for array lengths is unstable
-    //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
 }
 
 fn main() {