about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <46493976+workingjubilee@users.noreply.github.com>2021-09-11 08:23:41 -0700
committerGitHub <noreply@github.com>2021-09-11 08:23:41 -0700
commit746eb1d84defe2892a2d24a6029e8e7ec478a18f (patch)
tree074197ecd3cd755f37fab6480d69480100cda09c
parent7b514cdcfed05f6f09dfb529ea6669cff2796593 (diff)
parent804ccfaaabf6658b80d7b99828609986692a81ef (diff)
downloadrust-746eb1d84defe2892a2d24a6029e8e7ec478a18f.tar.gz
rust-746eb1d84defe2892a2d24a6029e8e7ec478a18f.zip
Rollup merge of #88733 - Noble-Mushtak:88577, r=estebank
Fix ICE for functions with more than 65535 arguments

This pull request fixes #88577 by changing the `param_idx` field in the `Param` variant of `WellFormedLoc` from `u16` to `u32`, thus allowing for more than 65,535 arguments in a function. Note that I also added a regression test, but needed to add `// ignore-tidy-filelength` because the test is more than 8000 lines long.
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs14
-rw-r--r--src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs12
-rw-r--r--src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr13
3 files changed, 39 insertions, 0 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index aca4503903c..e9dce953c73 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -422,11 +422,25 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
+        self.check_decl_num_args(fn_decl);
         self.check_decl_cvaradic_pos(fn_decl);
         self.check_decl_attrs(fn_decl);
         self.check_decl_self_param(fn_decl, self_semantic);
     }
 
+    /// Emits fatal error if function declaration has more than `u16::MAX` arguments
+    /// Error is fatal to prevent errors during typechecking
+    fn check_decl_num_args(&self, fn_decl: &FnDecl) {
+        let max_num_args: usize = u16::MAX.into();
+        if fn_decl.inputs.len() > max_num_args {
+            let Param { span, .. } = fn_decl.inputs[0];
+            self.err_handler().span_fatal(
+                span,
+                &format!("function can not have more than {} arguments", max_num_args),
+            );
+        }
+    }
+
     fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs
new file mode 100644
index 00000000000..e50cc586515
--- /dev/null
+++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs
@@ -0,0 +1,12 @@
+macro_rules! many_args {
+    ([$($t:tt)*]#$($h:tt)*) => {
+        many_args!{[$($t)*$($t)*]$($h)*}
+    };
+    ([$($t:tt)*]) => {
+        fn _f($($t: ()),*) {} //~ ERROR function can not have more than 65535 arguments
+    }
+}
+
+many_args!{[_]########## ######}
+
+fn main() {}
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
new file mode 100644
index 00000000000..615fd2ccb04
--- /dev/null
+++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
@@ -0,0 +1,13 @@
+error: function can not have more than 65535 arguments
+  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+   |
+LL |           fn _f($($t: ()),*) {}
+   |  ________________________^
+LL | |     }
+LL | | }
+LL | |
+LL | | many_args!{[_]########## ######}
+   | |____________^
+
+error: aborting due to previous error
+