diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 8f194ae88ab96..1d737e17e821b 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 3333719056240..126bab68ae351 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 df17879a9676e..e4904a0437b63 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 7facf8a4016b0..2855cea80b212 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 0000000000000..1a4173e1252d7 --- /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 0000000000000..cc33427f59d04 --- /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`.