about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBoxy <rust@boxyuwu.dev>2025-01-20 06:34:57 +0000
committerBoxy <rust@boxyuwu.dev>2025-01-23 06:01:36 +0000
commitc58fe21cb919aedce5408f478c86b19e8e17bab2 (patch)
tree51bb415ad5cd238a9003f3091b3a59e481e6fd40
parent1983c437ce7e94507402610de7e946a5f1fa73ed (diff)
downloadrust-c58fe21cb919aedce5408f478c86b19e8e17bab2.tar.gz
rust-c58fe21cb919aedce5408f478c86b19e8e17bab2.zip
Handle parenthesised infer args
-rw-r--r--compiler/rustc_ast/src/ast.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs17
-rw-r--r--tests/ui/const-generics/generic_arg_infer/parend_infer.rs12
3 files changed, 32 insertions, 6 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 98b9d7c9004..727fd59c6b3 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -288,6 +288,7 @@ impl ParenthesizedArgs {
     }
 }
 
+use crate::AstDeref;
 pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
 
 /// Modifiers on a trait bound like `~const`, `?` and `!`.
@@ -2166,6 +2167,14 @@ impl Ty {
         }
         final_ty
     }
+
+    pub fn is_maybe_parenthesised_infer(&self) -> bool {
+        match &self.kind {
+            TyKind::Infer => true,
+            TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
+            _ => false,
+        }
+    }
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 933079938ae..b9f1a4220b8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1084,17 +1084,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         match arg {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
             ast::GenericArg::Type(ty) => {
+                // We cannot just match on `TyKind::Infer` as `(_)` is represented as
+                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`
+                if ty.is_maybe_parenthesised_infer() {
+                    return GenericArg::Infer(hir::InferArg {
+                        hir_id: self.lower_node_id(ty.id),
+                        span: self.lower_span(ty.span),
+                    });
+                }
+
                 match &ty.kind {
-                    TyKind::Infer => {
-                        return GenericArg::Infer(hir::InferArg {
-                            hir_id: self.lower_node_id(ty.id),
-                            span: self.lower_span(ty.span),
-                        });
-                    }
                     // We parse const arguments as path types as we cannot distinguish them during
                     // parsing. We try to resolve that ambiguity by attempting resolution in both the
                     // type and value namespaces. If we resolved the path in the value namespace, we
                     // transform it into a generic const argument.
+                    //
+                    // FIXME: Should we be handling `(PATH_TO_CONST)`?
                     TyKind::Path(None, path) => {
                         if let Some(res) = self
                             .resolver
diff --git a/tests/ui/const-generics/generic_arg_infer/parend_infer.rs b/tests/ui/const-generics/generic_arg_infer/parend_infer.rs
new file mode 100644
index 00000000000..81c42183b38
--- /dev/null
+++ b/tests/ui/const-generics/generic_arg_infer/parend_infer.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+//@ revisions: gate nogate
+#![cfg_attr(gate, feature(generic_arg_infer))]
+
+fn main() {
+    // AST Types preserve parens for pretty printing reasons. This means
+    // that this is parsed as a `TyKind::Paren(TyKind::Infer)`. Generic
+    // arg lowering therefore needs to take into account not just `TyKind::Infer`
+    // but `TyKind::Infer` wrapped in arbitrarily many `TyKind::Paren`.
+    let a: Vec<(_)> = vec![1_u8];
+    let a: Vec<(((((_)))))> = vec![1_u8];
+}