about summary refs log tree commit diff
diff options
context:
space:
mode:
authorr0cky <mu001999@outlook.com>2023-12-18 22:24:10 +0800
committerr0cky <mu001999@outlook.com>2023-12-18 22:24:10 +0800
commita7d6f42db361582645c7ee8d112d5126592177e5 (patch)
tree5dfb186455b685e6497cc5c1aa9368ea8e05166f
parent5e7025419d1b1359e4cb7cd365ba5900c8299089 (diff)
downloadrust-a7d6f42db361582645c7ee8d112d5126592177e5.tar.gz
rust-a7d6f42db361582645c7ee8d112d5126592177e5.zip
Check generic params after sigature for main-fn-ty
-rw-r--r--compiler/rustc_hir_analysis/src/check/entry.rs49
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs51
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs4
-rw-r--r--tests/ui/entry-point/issue-118772.rs3
-rw-r--r--tests/ui/entry-point/issue-118772.stderr12
6 files changed, 69 insertions, 52 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs
index 8f194ae88ab..1d737e17e82 100644
--- a/compiler/rustc_hir_analysis/src/check/entry.rs
+++ b/compiler/rustc_hir_analysis/src/check/entry.rs
@@ -92,24 +92,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
 
     let mut error = false;
     let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
-    let main_fn_generics = tcx.generics_of(main_def_id);
-    let main_fn_predicates = tcx.predicates_of(main_def_id);
-    if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
-        let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
-        tcx.sess.emit_err(errors::MainFunctionGenericParameters {
-            span: generics_param_span.unwrap_or(main_span),
-            label_span: generics_param_span,
-        });
-        error = true;
-    } else if !main_fn_predicates.predicates.is_empty() {
-        // generics may bring in implicit predicates, so we skip this check if generics is present.
-        let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
-        tcx.sess.emit_err(errors::WhereClauseOnMain {
-            span: generics_where_clauses_span.unwrap_or(main_span),
-            generics_span: generics_where_clauses_span,
-        });
-        error = true;
-    }
 
     let main_asyncness = tcx.asyncness(main_def_id);
     if main_asyncness.is_async() {
@@ -142,10 +124,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
     if let Some(term_did) = tcx.lang_items().termination() {
         let return_ty = main_fnsig.output();
         let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
-        if !return_ty.bound_vars().is_empty() {
-            tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
-            error = true;
-        }
         let return_ty = return_ty.skip_binder();
         let infcx = tcx.infer_ctxt().build();
         let cause = traits::ObligationCause::new(
@@ -180,7 +158,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
         Abi::Rust,
     ));
 
-    check_function_signature(
+    if check_function_signature(
         tcx,
         ObligationCause::new(
             main_span,
@@ -189,7 +167,28 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
         ),
         main_def_id,
         expected_sig,
-    );
+    )
+    .is_err()
+    {
+        return;
+    }
+
+    let main_fn_generics = tcx.generics_of(main_def_id);
+    let main_fn_predicates = tcx.predicates_of(main_def_id);
+    if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
+        let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
+        tcx.sess.emit_err(errors::MainFunctionGenericParameters {
+            span: generics_param_span.unwrap_or(main_span),
+            label_span: generics_param_span,
+        });
+    } else if !main_fn_predicates.predicates.is_empty() {
+        // generics may bring in implicit predicates, so we skip this check if generics is present.
+        let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
+        tcx.sess.emit_err(errors::WhereClauseOnMain {
+            span: generics_where_clauses_span.unwrap_or(main_span),
+            generics_span: generics_where_clauses_span,
+        });
+    }
 }
 
 fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
@@ -255,7 +254,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
                 Abi::Rust,
             ));
 
-            check_function_signature(
+            let _ = check_function_signature(
                 tcx,
                 ObligationCause::new(
                     start_span,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 33337190562..126bab68ae3 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -55,7 +55,7 @@ fn equate_intrinsic_type<'tcx>(
         && gen_count_ok(own_counts.consts, n_cts, "const")
     {
         let it_def_id = it.owner_id.def_id;
-        check_function_signature(
+        let _ = check_function_signature(
             tcx,
             ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
             it_def_id.into(),
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index df17879a967..e4904a0437b 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -77,6 +77,7 @@ use std::num::NonZeroU32;
 
 use check::check_mod_item_types;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::ErrorGuaranteed;
 use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
@@ -570,7 +571,26 @@ pub fn check_function_signature<'tcx>(
     mut cause: ObligationCause<'tcx>,
     fn_id: DefId,
     expected_sig: ty::PolyFnSig<'tcx>,
-) {
+) -> Result<(), ErrorGuaranteed> {
+    fn extract_span_for_error_reporting<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        err: TypeError<'_>,
+        cause: &ObligationCause<'tcx>,
+        fn_id: LocalDefId,
+    ) -> rustc_span::Span {
+        let mut args = {
+            let node = tcx.hir().expect_owner(fn_id);
+            let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
+            decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
+        };
+
+        match err {
+            TypeError::ArgumentMutability(i)
+            | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
+            _ => cause.span(),
+        }
+    }
+
     let local_id = fn_id.as_local().unwrap_or(CRATE_DEF_ID);
 
     let param_env = ty::ParamEnv::empty();
@@ -587,8 +607,7 @@ pub fn check_function_signature<'tcx>(
         Ok(()) => {
             let errors = ocx.select_all_or_error();
             if !errors.is_empty() {
-                infcx.err_ctxt().report_fulfillment_errors(errors);
-                return;
+                return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
             }
         }
         Err(err) => {
@@ -610,30 +629,14 @@ pub fn check_function_signature<'tcx>(
                 false,
                 false,
             );
-            diag.emit();
-            return;
+            return Err(diag.emit());
         }
     }
 
     let outlives_env = OutlivesEnvironment::new(param_env);
-    let _ = ocx.resolve_regions_and_report_errors(local_id, &outlives_env);
-
-    fn extract_span_for_error_reporting<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        err: TypeError<'_>,
-        cause: &ObligationCause<'tcx>,
-        fn_id: LocalDefId,
-    ) -> rustc_span::Span {
-        let mut args = {
-            let node = tcx.hir().expect_owner(fn_id);
-            let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
-            decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
-        };
-
-        match err {
-            TypeError::ArgumentMutability(i)
-            | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
-            _ => cause.span(),
-        }
+    if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) {
+        return Err(e);
     }
+
+    Ok(())
 }
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 7facf8a4016..2855cea80b2 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -261,7 +261,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         bounds,
     );
 
-    check_function_signature(
+    let _ = check_function_signature(
         tcx,
         ObligationCause::new(
             tcx.def_span(fn_id),
@@ -300,7 +300,7 @@ fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id:
         Abi::Rust,
     ));
 
-    check_function_signature(
+    let _ = check_function_signature(
         tcx,
         ObligationCause::new(
             tcx.def_span(def_id),
diff --git a/tests/ui/entry-point/issue-118772.rs b/tests/ui/entry-point/issue-118772.rs
new file mode 100644
index 00000000000..1a4173e1252
--- /dev/null
+++ b/tests/ui/entry-point/issue-118772.rs
@@ -0,0 +1,3 @@
+fn main(_: &i32) { //~ ERROR `main` function has wrong type
+    println!("Hello, world!");
+}
diff --git a/tests/ui/entry-point/issue-118772.stderr b/tests/ui/entry-point/issue-118772.stderr
new file mode 100644
index 00000000000..cc33427f59d
--- /dev/null
+++ b/tests/ui/entry-point/issue-118772.stderr
@@ -0,0 +1,12 @@
+error[E0580]: `main` function has wrong type
+  --> $DIR/issue-118772.rs:1:1
+   |
+LL | fn main(_: &i32) {
+   | ^^^^^^^^^^^^^^^^ incorrect number of function parameters
+   |
+   = note: expected signature `fn()`
+              found signature `for<'a> fn(&'a i32)`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0580`.