rustc_hir_analysis: add a helper to check function the signature mismatches

This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions.

The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
This commit is contained in:
Eduardo Sánchez Muñoz 2023-09-17 20:13:05 +02:00
parent 0692db1a90
commit c599761140
48 changed files with 423 additions and 385 deletions

View File

@ -11,8 +11,8 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use std::ops::Not;
use super::check_function_signature;
use crate::errors;
use crate::require_same_types;
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
@ -162,33 +162,33 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
error = true;
}
// now we can take the return type of the given main function
expected_return_type = main_fnsig.output();
expected_return_type = norm_return_ty;
} else {
// standard () main return type
expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx));
expected_return_type = tcx.types.unit;
}
if error {
return;
}
let se_ty = Ty::new_fn_ptr(
tcx,
expected_return_type.map_bound(|expected_return_type| {
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
}),
);
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[],
expected_return_type,
false,
hir::Unsafety::Normal,
Abi::Rust,
));
require_same_types(
check_function_signature(
tcx,
&ObligationCause::new(
ObligationCause::new(
main_span,
main_diagnostics_def_id,
ObligationCauseCode::MainFunctionType,
),
param_env,
se_ty,
Ty::new_fn_ptr(tcx, main_fnsig),
main_def_id,
expected_sig,
);
}
@ -247,27 +247,23 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
}
}
let se_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Unsafety::Normal,
Abi::Rust,
)),
);
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Unsafety::Normal,
Abi::Rust,
));
require_same_types(
check_function_signature(
tcx,
&ObligationCause::new(
ObligationCause::new(
start_span,
start_def_id,
ObligationCauseCode::StartFunctionType,
),
ty::ParamEnv::empty(), // start should not have any where bounds.
se_ty,
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
start_def_id.into(),
expected_sig,
);
}
_ => {

View File

@ -1,11 +1,11 @@
//! Type-checking for the rust-intrinsic and platform-intrinsic
//! intrinsics that the compiler exposes.
use crate::check::check_function_signature;
use crate::errors::{
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
WrongNumberOfGenericArgumentsToIntrinsic,
};
use crate::require_same_types;
use hir::def_id::DefId;
use rustc_errors::{struct_span_err, DiagnosticMessage};
@ -53,15 +53,12 @@ fn equate_intrinsic_type<'tcx>(
&& gen_count_ok(own_counts.types, n_tps, "type")
&& gen_count_ok(own_counts.consts, 0, "const")
{
let fty = Ty::new_fn_ptr(tcx, sig);
let it_def_id = it.owner_id.def_id;
let cause = ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType);
require_same_types(
check_function_signature(
tcx,
&cause,
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).instantiate_identity()),
fty,
ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
it_def_id.into(),
sig,
);
}
}

View File

@ -73,23 +73,31 @@ pub mod wfcheck;
pub use check::check_abi;
use std::num::NonZeroU32;
use check::check_mod_item_types;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, TyCtxtInferExt as _};
use rustc_infer::traits::ObligationCause;
use rustc_middle::query::Providers;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_session::parse::feature_err;
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, BytePos, Span, Symbol};
use rustc_span::{self, def_id::CRATE_DEF_ID, BytePos, Span, Symbol};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use std::num::NonZeroU32;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt;
use crate::errors;
use crate::require_c_abi_if_c_variadic;
@ -546,3 +554,82 @@ fn bad_non_zero_sized_fields<'tcx>(
pub fn potentially_plural_count(count: usize, word: &str) -> String {
format!("{} {}{}", count, word, pluralize!(count))
}
pub fn check_function_signature<'tcx>(
tcx: TyCtxt<'tcx>,
mut cause: ObligationCause<'tcx>,
fn_id: DefId,
expected_sig: ty::PolyFnSig<'tcx>,
) {
let local_id = fn_id.as_local().unwrap_or(CRATE_DEF_ID);
let param_env = ty::ParamEnv::empty();
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
let unnormalized_actual_sig = infcx.instantiate_binder_with_fresh_vars(
cause.span,
infer::HigherRankedType,
tcx.fn_sig(fn_id).instantiate_identity(),
);
let norm_cause = ObligationCause::misc(cause.span, local_id);
let actual_sig = ocx.normalize(&norm_cause, param_env, unnormalized_actual_sig);
let expected_sig = tcx.liberate_late_bound_regions(fn_id, expected_sig);
match ocx.eq(&cause, param_env, expected_sig, actual_sig) {
Ok(()) => {
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors);
return;
}
}
Err(err) => {
let err_ctxt = infcx.err_ctxt();
if fn_id.is_local() {
cause.span = extract_span_for_error_reporting(tcx, err, &cause, local_id);
}
let failure_code = cause.as_failure_code_diag(err, cause.span, vec![]);
let mut diag = tcx.sess.create_err(failure_code);
err_ctxt.note_type_err(
&mut diag,
&cause,
None,
Some(infer::ValuePairs::Sigs(ExpectedFound {
expected: expected_sig,
found: actual_sig,
})),
err,
false,
false,
);
diag.emit();
return;
}
}
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(),
}
}
}

View File

@ -99,7 +99,6 @@ use rustc_errors::ErrorGuaranteed;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir as hir;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::middle;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -107,8 +106,7 @@ use rustc_middle::util;
use rustc_session::parse::feature_err;
use rustc_span::{symbol::sym, Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt};
use rustc_trait_selection::traits;
use astconv::{AstConv, OnlySelfBounds};
use bounds::Bounds;
@ -151,28 +149,6 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
}
fn require_same_types<'tcx>(
tcx: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) {
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);
match ocx.eq(cause, param_env, expected, actual) {
Ok(()) => {
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors);
}
}
Err(err) => {
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
}
}
}
pub fn provide(providers: &mut Providers) {
collect::provide(providers);
coherence::provide(providers);

View File

@ -83,16 +83,6 @@ hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*cons
hir_typeck_invalid_callee = expected function, found {$ty}
hir_typeck_lang_start_expected_sig_note = the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item
hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count}
hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` lang item is incorrect
.suggestion = change the type from `{$found_ty}` to `{$expected_ty}`
hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect
.suggestion = change the type from `{$found_ty}` to `{$expected_ty}`
hir_typeck_lossy_provenance_int2ptr =
strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`
.suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address

View File

@ -1,7 +1,6 @@
use std::cell::RefCell;
use crate::coercion::CoerceMany;
use crate::errors::{
LangStartIncorrectNumberArgs, LangStartIncorrectParam, LangStartIncorrectRetTy,
};
use crate::gather_locals::GatherLocalsVisitor;
use crate::FnCtxt;
use crate::GeneratorTypes;
@ -9,14 +8,15 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir_analysis::check::fn_maybe_err;
use rustc_hir_analysis::check::{check_function_signature, fn_maybe_err};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::RegionVariableOrigin;
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::sym;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
use std::cell::RefCell;
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
/// Helper used for fns and closures. Does the grungy work of checking a function
/// body and returns the function context used for that purpose, since in the case of a fn item
@ -166,52 +166,17 @@ pub(super) fn check_fn<'a, 'tcx>(
if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
&& panic_impl_did == fn_def_id.to_def_id()
{
check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty);
check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig);
}
if let Some(lang_start_defid) = tcx.lang_items().start_fn() && lang_start_defid == fn_def_id.to_def_id() {
check_lang_start_fn(tcx, fn_sig, decl, fn_def_id);
check_lang_start_fn(tcx, fn_sig, fn_def_id);
}
gen_ty
}
fn check_panic_info_fn(
tcx: TyCtxt<'_>,
fn_id: LocalDefId,
fn_sig: ty::FnSig<'_>,
decl: &hir::FnDecl<'_>,
declared_ret_ty: Ty<'_>,
) {
let Some(panic_info_did) = tcx.lang_items().panic_info() else {
tcx.sess.err("language item required, but not found: `panic_info`");
return;
};
if *declared_ret_ty.kind() != ty::Never {
tcx.sess.span_err(decl.output.span(), "return type should be `!`");
}
let inputs = fn_sig.inputs();
if inputs.len() != 1 {
tcx.sess.span_err(tcx.def_span(fn_id), "function should have one argument");
return;
}
let arg_is_panic_info = match *inputs[0].kind() {
ty::Ref(region, ty, mutbl) => match *ty.kind() {
ty::Adt(ref adt, _) => {
adt.did() == panic_info_did && mutbl.is_not() && !region.is_static()
}
_ => false,
},
_ => false,
};
if !arg_is_panic_info {
tcx.sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
}
fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {
let DefKind::Fn = tcx.def_kind(fn_id) else {
let span = tcx.def_span(fn_id);
tcx.sess.span_err(span, "should be a function");
@ -227,125 +192,87 @@ fn check_panic_info_fn(
let span = tcx.def_span(fn_id);
tcx.sess.span_err(span, "should have no const parameters");
}
let Some(panic_info_did) = tcx.lang_items().panic_info() else {
tcx.sess.err("language item required, but not found: `panic_info`");
return;
};
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
tcx,
&[ty::GenericArg::from(ty::Region::new_late_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon(None) },
))],
);
let panic_info_ref_ty = Ty::new_imm_ref(
tcx,
ty::Region::new_late_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
),
panic_info_ty,
);
let bounds = tcx.mk_bound_variable_kinds(&[
ty::BoundVariableKind::Region(ty::BrAnon(None)),
ty::BoundVariableKind::Region(ty::BrAnon(None)),
]);
let expected_sig = ty::Binder::bind_with_vars(
tcx.mk_fn_sig([panic_info_ref_ty], tcx.types.never, false, fn_sig.unsafety, Abi::Rust),
bounds,
);
check_function_signature(
tcx,
ObligationCause::new(
tcx.def_span(fn_id),
fn_id,
ObligationCauseCode::LangFunctionType(sym::panic_impl),
),
fn_id.into(),
expected_sig,
);
}
fn check_lang_start_fn<'tcx>(
tcx: TyCtxt<'tcx>,
fn_sig: ty::FnSig<'tcx>,
decl: &'tcx hir::FnDecl<'tcx>,
def_id: LocalDefId,
) {
let inputs = fn_sig.inputs();
fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: LocalDefId) {
// build type `fn(main: fn() -> T, argc: isize, argv: *const *const u8, sigpipe: u8)`
let arg_count = inputs.len();
if arg_count != 4 {
tcx.sess.emit_err(LangStartIncorrectNumberArgs {
params_span: tcx.def_span(def_id),
found_param_count: arg_count,
});
}
// make a Ty for the generic on the fn for diagnostics
// FIXME: make the lang item generic checks check for the right generic *kind*
// for example `start`'s generic should be a type parameter
let generics = tcx.generics_of(def_id);
let fn_generic = generics.param_at(0, tcx);
let generic_ty = Ty::new_param(tcx, fn_generic.index, fn_generic.name);
let main_fn_ty = Ty::new_fn_ptr(
tcx,
Binder::dummy(tcx.mk_fn_sig([], generic_ty, false, hir::Unsafety::Normal, Abi::Rust)),
);
// only check args if they should exist by checking the count
// note: this does not handle args being shifted or their order swapped very nicely
// but it's a lang item, users shouldn't frequently encounter this
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[
main_fn_ty,
tcx.types.isize,
Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8)),
tcx.types.u8,
],
tcx.types.isize,
false,
fn_sig.unsafety,
Abi::Rust,
));
// first arg is `main: fn() -> T`
if let Some(&main_arg) = inputs.get(0) {
// make a Ty for the generic on the fn for diagnostics
// FIXME: make the lang item generic checks check for the right generic *kind*
// for example `start`'s generic should be a type parameter
let generics = tcx.generics_of(def_id);
let fn_generic = generics.param_at(0, tcx);
let generic_ty = Ty::new_param(tcx, fn_generic.index, fn_generic.name);
let expected_fn_sig =
tcx.mk_fn_sig([], generic_ty, false, hir::Unsafety::Normal, Abi::Rust);
let expected_ty = Ty::new_fn_ptr(tcx, Binder::dummy(expected_fn_sig));
// we emit the same error to suggest changing the arg no matter what's wrong with the arg
let emit_main_fn_arg_err = || {
tcx.sess.emit_err(LangStartIncorrectParam {
param_span: decl.inputs[0].span,
param_num: 1,
expected_ty: expected_ty,
found_ty: main_arg,
});
};
if let ty::FnPtr(main_fn_sig) = main_arg.kind() {
let main_fn_inputs = main_fn_sig.inputs();
if main_fn_inputs.iter().count() != 0 {
emit_main_fn_arg_err();
}
let output = main_fn_sig.output();
output.map_bound(|ret_ty| {
// if the output ty is a generic, it's probably the right one
if !matches!(ret_ty.kind(), ty::Param(_)) {
emit_main_fn_arg_err();
}
});
} else {
emit_main_fn_arg_err();
}
}
// second arg is isize
if let Some(&argc_arg) = inputs.get(1) {
if argc_arg != tcx.types.isize {
tcx.sess.emit_err(LangStartIncorrectParam {
param_span: decl.inputs[1].span,
param_num: 2,
expected_ty: tcx.types.isize,
found_ty: argc_arg,
});
}
}
// third arg is `*const *const u8`
if let Some(&argv_arg) = inputs.get(2) {
let mut argv_is_okay = false;
if let ty::RawPtr(outer_ptr) = argv_arg.kind() {
if outer_ptr.mutbl.is_not() {
if let ty::RawPtr(inner_ptr) = outer_ptr.ty.kind() {
if inner_ptr.mutbl.is_not() && inner_ptr.ty == tcx.types.u8 {
argv_is_okay = true;
}
}
}
}
if !argv_is_okay {
let inner_ptr_ty =
Ty::new_ptr(tcx, ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: tcx.types.u8 });
let expected_ty =
Ty::new_ptr(tcx, ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: inner_ptr_ty });
tcx.sess.emit_err(LangStartIncorrectParam {
param_span: decl.inputs[2].span,
param_num: 3,
expected_ty,
found_ty: argv_arg,
});
}
}
// fourth arg is `sigpipe: u8`
if let Some(&sigpipe_arg) = inputs.get(3) {
if sigpipe_arg != tcx.types.u8 {
tcx.sess.emit_err(LangStartIncorrectParam {
param_span: decl.inputs[3].span,
param_num: 4,
expected_ty: tcx.types.u8,
found_ty: sigpipe_arg,
});
}
}
// output type is isize
if fn_sig.output() != tcx.types.isize {
tcx.sess.emit_err(LangStartIncorrectRetTy {
ret_span: decl.output.span(),
expected_ty: tcx.types.isize,
found_ty: fn_sig.output(),
});
}
check_function_signature(
tcx,
ObligationCause::new(
tcx.def_span(def_id),
def_id,
ObligationCauseCode::LangFunctionType(sym::start),
),
def_id.into(),
expected_sig,
);
}

View File

@ -236,39 +236,6 @@ impl AddToDiagnostic for TypeMismatchFruTypo {
}
}
#[derive(Diagnostic)]
#[diag(hir_typeck_lang_start_incorrect_number_params)]
#[note(hir_typeck_lang_start_incorrect_number_params_note_expected_count)]
#[note(hir_typeck_lang_start_expected_sig_note)]
pub struct LangStartIncorrectNumberArgs {
#[primary_span]
pub params_span: Span,
pub found_param_count: usize,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_lang_start_incorrect_param)]
pub struct LangStartIncorrectParam<'tcx> {
#[primary_span]
#[suggestion(style = "short", code = "{expected_ty}", applicability = "machine-applicable")]
pub param_span: Span,
pub param_num: usize,
pub expected_ty: Ty<'tcx>,
pub found_ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_lang_start_incorrect_ret_ty)]
pub struct LangStartIncorrectRetTy<'tcx> {
#[primary_span]
#[suggestion(style = "short", code = "{expected_ty}", applicability = "machine-applicable")]
pub ret_span: Span,
pub expected_ty: Ty<'tcx>,
pub found_ty: Ty<'tcx>,
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_lossy_provenance_int2ptr)]
#[help]

View File

@ -198,6 +198,10 @@ infer_nothing = {""}
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
infer_oc_closure_selfref = closure/generator type that references itself
infer_oc_const_compat = const not compatible with trait
infer_oc_fn_lang_correct_type = {$lang_item_name ->
[panic_impl] `#[panic_handler]`
*[lang_item_name] lang item `{$lang_item_name}`
} function has wrong type
infer_oc_fn_main_correct_type = `main` function has wrong type
infer_oc_fn_start_correct_type = `#[start]` function has wrong type
infer_oc_generic = mismatched types
@ -337,6 +341,7 @@ infer_subtype = ...so that the {$requirement ->
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_start_correct_type] `#[start]` function has the correct type
[fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible
@ -350,6 +355,7 @@ infer_subtype_2 = ...so that {$requirement ->
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_start_correct_type] `#[start]` function has the correct type
[fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible

View File

@ -1463,6 +1463,14 @@ pub enum ObligationCauseFailureCode {
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_fn_lang_correct_type, code = "E0308")]
FnLangCorrectType {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
lang_item_name: Symbol,
},
#[diag(infer_oc_intrinsic_correct_type, code = "E0308")]
IntrinsicCorrectType {
#[primary_span]

View File

@ -2927,6 +2927,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
| IfExpression { .. }
| LetElse
| StartFunctionType
| LangFunctionType(_)
| IntrinsicType
| MethodReceiver => Error0308,
@ -2971,6 +2972,9 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
LetElse => ObligationCauseFailureCode::NoDiverge { span, subdiags },
MainFunctionType => ObligationCauseFailureCode::FnMainCorrectType { span },
StartFunctionType => ObligationCauseFailureCode::FnStartCorrectType { span, subdiags },
&LangFunctionType(lang_item_name) => {
ObligationCauseFailureCode::FnLangCorrectType { span, subdiags, lang_item_name }
}
IntrinsicType => ObligationCauseFailureCode::IntrinsicCorrectType { span, subdiags },
MethodReceiver => ObligationCauseFailureCode::MethodCorrectType { span, subdiags },
@ -3006,6 +3010,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
MainFunctionType => "`main` function has the correct type",
StartFunctionType => "`#[start]` function has the correct type",
LangFunctionType(_) => "lang item function has the correct type",
IntrinsicType => "intrinsic has the correct type",
MethodReceiver => "method receiver has the correct type",
_ => "types are compatible",
@ -3028,6 +3033,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
IfExpressionWithNoElse => "no_else",
MainFunctionType => "fn_main_correct_type",
StartFunctionType => "fn_start_correct_type",
LangFunctionType(_) => "fn_lang_correct_type",
IntrinsicType => "intrinsic_correct_type",
MethodReceiver => "method_correct_type",
_ => "other",

View File

@ -378,6 +378,9 @@ pub enum ObligationCauseCode<'tcx> {
/// `start` has wrong type
StartFunctionType,
/// language function has wrong type
LangFunctionType(Symbol),
/// Intrinsic has wrong type
IntrinsicType,

View File

@ -2711,6 +2711,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
| ObligationCauseCode::IfExpressionWithNoElse
| ObligationCauseCode::MainFunctionType
| ObligationCauseCode::StartFunctionType
| ObligationCauseCode::LangFunctionType(_)
| ObligationCauseCode::IntrinsicType
| ObligationCauseCode::MethodReceiver
| ObligationCauseCode::ReturnNoExpression

View File

@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn()`
found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))`
= note: expected signature `fn()`
found signature `fn(for<'a> fn(&'a ()))`
error: aborting due to previous error

View File

@ -9,7 +9,7 @@ extern {}
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
//~^ ERROR: incorrect number of parameters for the `start` lang item
//~^ ERROR lang item `start` function has wrong type [E0308]
40+2
}

View File

@ -1,11 +1,12 @@
error: incorrect number of parameters for the `start` lang item
error[E0308]: lang item `start` function has wrong type
--> $DIR/issue-92157.rs:11:1
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: the `start` lang item should have four parameters, but found 3
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
found signature `fn(fn() -> T, isize, *const *const u8) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,2 @@
pub fn boilerplate(x: u8) {}
//~^ ERROR: `main` function has wrong type [E0580]

View File

@ -0,0 +1,6 @@
// aux-build:bad_main_functions.rs
#![feature(imported_main)]
extern crate bad_main_functions;
pub use bad_main_functions::boilerplate as main;

View File

@ -0,0 +1,12 @@
error[E0580]: `main` function has wrong type
--> $DIR/auxiliary/bad_main_functions.rs:1:1
|
LL | pub fn boilerplate(x: u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected signature `fn()`
found signature `fn(u8)`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0580`.

View File

@ -1,11 +1,11 @@
error[E0308]: intrinsic has wrong type
--> $DIR/E0308.rs:6:5
--> $DIR/E0308.rs:6:20
|
LL | fn size_of<T>();
| ^^^^^^^^^^^^^^^^ expected `()`, found `usize`
| ^ expected `usize`, found `()`
|
= note: expected fn pointer `extern "rust-intrinsic" fn()`
found fn pointer `extern "rust-intrinsic" fn() -> usize`
= note: expected signature `extern "rust-intrinsic" fn() -> usize`
found signature `extern "rust-intrinsic" fn()`
error: aborting due to previous error

View File

@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
LL | extern "C" fn main() {}
| ^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn
|
= note: expected fn pointer `fn()`
found fn pointer `extern "C" fn()`
= note: expected signature `fn()`
found signature `extern "C" fn()`
error: aborting due to previous error

View File

@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
LL | fn main(x: isize) { }
| ^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn()`
found fn pointer `fn(isize)`
= note: expected signature `fn()`
found signature `fn(isize)`
error: aborting due to previous error

View File

@ -4,8 +4,8 @@ error[E0308]: `#[start]` function has wrong type
LL | fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn(isize, *const *const u8) -> _`
found fn pointer `fn(isize, *const *const u8, *const u8) -> _`
= note: expected signature `fn(isize, *const *const u8) -> _`
found signature `fn(isize, *const *const u8, *const u8) -> _`
error: aborting due to previous error

View File

@ -1,8 +1,12 @@
error: parameter 2 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:75:38
|
LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ^^ help: change the type from `i8` to `isize`
| ^^ expected `isize`, found `i8`
|
= note: expected signature `fn(fn() -> _, isize, _, _) -> _`
found signature `fn(fn() -> _, i8, _, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,8 +1,12 @@
error: parameter 3 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:89:52
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize {
| ^^ help: change the type from `u8` to `*const *const u8`
| ^^ expected `*const *const u8`, found `u8`
|
= note: expected signature `fn(fn() -> _, _, *const *const u8, _) -> _`
found signature `fn(fn() -> _, _, u8, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,13 +1,12 @@
error: parameter 3 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:82:52
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize {
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ expected `u8`, found `usize`
|
help: change the type from `*const *const usize` to `*const *const u8`
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ~~~~~~~~~~~~~~~~
= note: expected signature `fn(fn() -> _, _, *const *const u8, _) -> _`
found signature `fn(fn() -> _, _, *const *const usize, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,13 +1,12 @@
error: parameter 1 of the `start` lang item is incorrect
--> $DIR/start_lang_item_args.rs:61:20
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:61:1
|
LL | fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
help: change the type from `fn(i32) -> T` to `fn() -> T`
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ~~~~~~~~~
= note: expected signature `fn(fn() -> _, _, _, _) -> _`
found signature `fn(fn(i32) -> _, _, _, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,13 +1,14 @@
error: parameter 1 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:68:20
|
LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ^^^^^^^^^^^
| - ^^^^^^^^^^^ expected type parameter `T`, found `u16`
| |
| this type parameter
|
help: change the type from `fn() -> u16` to `fn() -> T`
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ~~~~~~~~~
= note: expected signature `fn(fn() -> T, _, _, _) -> _`
found signature `fn(fn() -> u16, _, _, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,8 +1,12 @@
error: parameter 1 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:54:20
|
LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
| ^^^ help: change the type from `u64` to `fn() -> T`
| ^^^ expected fn pointer, found `u64`
|
= note: expected signature `fn(fn() -> T, _, _, _) -> _`
found signature `fn(u64, _, _, _) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,11 +1,12 @@
error: incorrect number of parameters for the `start` lang item
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:15:1
|
LL | fn start<T>() -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: the `start` lang item should have four parameters, but found 0
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
found signature `fn() -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,8 +1,12 @@
error: the return type of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:29:84
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
| ^ help: change the type from `()` to `isize`
| ^ expected `isize`, found `()`
|
= note: expected signature `fn(fn() -> _, _, _, _) -> isize`
found signature `fn(fn() -> _, _, _, _)`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,11 +1,12 @@
error: incorrect number of parameters for the `start` lang item
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:22:1
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: the `start` lang item should have four parameters, but found 3
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
found signature `fn(fn() -> T, isize, *const *const u8) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -13,33 +13,33 @@ pub trait Sized {}
#[cfg(missing_all_args)]
#[lang = "start"]
fn start<T>() -> isize {
//[missing_all_args]~^ ERROR incorrect number of parameters
//[missing_all_args]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(missing_sigpipe_arg)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
//[missing_sigpipe_arg]~^ ERROR incorrect number of parameters
//[missing_sigpipe_arg]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(missing_ret)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
//[missing_ret]~^ ERROR the return type of the `start` lang item is incorrect
//[missing_ret]~^ ERROR lang item `start` function has wrong type [E0308]
#[cfg(start_ret)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 {
//[start_ret]~^ ERROR the return type of the `start` lang item is incorrect
//[start_ret]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(too_many_args)]
#[lang = "start"]
fn start<T>(
//[too_many_args]~^ ERROR incorrect number of parameters
//[too_many_args]~^ ERROR lang item `start` function has wrong type [E0308]
_main: fn() -> T,
_argc: isize,
_argv: *const *const u8,
@ -52,49 +52,49 @@ fn start<T>(
#[cfg(main_ty)]
#[lang = "start"]
fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
//[main_ty]~^ ERROR parameter 1 of the `start` lang item is incorrect
//[main_ty]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(main_args)]
#[lang = "start"]
fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
//[main_args]~^ ERROR parameter 1 of the `start` lang item is incorrect
//[main_args]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(main_ret)]
#[lang = "start"]
fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
//[main_ret]~^ ERROR parameter 1 of the `start` lang item is incorrect
//[main_ret]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(argc)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize {
//[argc]~^ ERROR parameter 2 of the `start` lang item is incorrect
//[argc]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(argv_inner_ptr)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize {
//[argv_inner_ptr]~^ ERROR parameter 3 of the `start` lang item is incorrect
//[argv_inner_ptr]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(argv)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize {
//[argv]~^ ERROR parameter 3 of the `start` lang item is incorrect
//[argv]~^ ERROR lang item `start` function has wrong type [E0308]
100
}
#[cfg(sigpipe)]
#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize {
//[sigpipe]~^ ERROR parameter 4 of the `start` lang item is incorrect
//[sigpipe]~^ ERROR lang item `start` function has wrong type [E0308]
100
}

View File

@ -1,8 +1,12 @@
error: parameter 4 of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:96:80
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize {
| ^^^ help: change the type from `i64` to `u8`
| ^^^ expected `u8`, found `i64`
|
= note: expected signature `fn(fn() -> _, _, _, u8) -> _`
found signature `fn(fn() -> _, _, _, i64) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,8 +1,12 @@
error: the return type of the `start` lang item is incorrect
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:34:87
|
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 {
| ^^ help: change the type from `u8` to `isize`
| ^^ expected `isize`, found `u8`
|
= note: expected signature `fn(fn() -> _, _, _, _) -> isize`
found signature `fn(fn() -> _, _, _, _) -> u8`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,4 +1,4 @@
error: incorrect number of parameters for the `start` lang item
error[E0308]: lang item `start` function has wrong type
--> $DIR/start_lang_item_args.rs:41:1
|
LL | / fn start<T>(
@ -8,10 +8,11 @@ LL | | _argc: isize,
... |
LL | | _extra_arg: (),
LL | | ) -> isize {
| |__________^
| |__________^ incorrect number of function parameters
|
= note: the `start` lang item should have four parameters, but found 5
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
found signature `fn(fn() -> T, isize, *const *const u8, u8, ()) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
LL | fn main(foo: S) {
| ^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn()`
found fn pointer `fn(S)`
= note: expected signature `fn()`
found signature `fn(S)`
error: aborting due to previous error

View File

@ -6,8 +6,5 @@
use core::panic::PanicInfo;
#[panic_handler]
fn panic(
info: PanicInfo, //~ ERROR argument should be `&PanicInfo`
) -> () //~ ERROR return type should be `!`
{
}
fn panic(info: PanicInfo) -> () {}
//~^ `#[panic_handler]` function has wrong type [E0308]

View File

@ -1,14 +1,12 @@
error: return type should be `!`
--> $DIR/panic-handler-bad-signature-1.rs:11:6
error[E0308]: `#[panic_handler]` function has wrong type
--> $DIR/panic-handler-bad-signature-1.rs:9:16
|
LL | ) -> ()
| ^^
error: argument should be `&PanicInfo`
--> $DIR/panic-handler-bad-signature-1.rs:10:11
LL | fn panic(info: PanicInfo) -> () {}
| ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>`
|
LL | info: PanicInfo,
| ^^^^^^^^^
= note: expected signature `fn(&PanicInfo<'_>) -> !`
found signature `fn(PanicInfo<'_>)`
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -6,9 +6,8 @@
use core::panic::PanicInfo;
#[panic_handler]
fn panic(
info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo`
) -> !
fn panic(info: &'static PanicInfo) -> !
//~^ #[panic_handler]` function has wrong type [E0308]
{
loop {}
}

View File

@ -1,8 +1,18 @@
error: argument should be `&PanicInfo`
--> $DIR/panic-handler-bad-signature-2.rs:10:11
error[E0308]: `#[panic_handler]` function has wrong type
--> $DIR/panic-handler-bad-signature-2.rs:9:1
|
LL | info: &'static PanicInfo,
| ^^^^^^^^^^^^^^^^^^
LL | fn panic(info: &'static PanicInfo) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&PanicInfo<'_>) -> _`
found signature `fn(&'static PanicInfo<'_>) -> _`
note: the anonymous lifetime as defined here...
--> $DIR/panic-handler-bad-signature-2.rs:9:1
|
LL | fn panic(info: &'static PanicInfo) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -6,6 +6,6 @@
use core::panic::PanicInfo;
#[panic_handler]
fn panic() -> ! { //~ ERROR function should have one argument
fn panic() -> ! { //~ #[panic_handler]` function has wrong type [E0308]
loop {}
}

View File

@ -1,8 +1,12 @@
error: function should have one argument
error[E0308]: `#[panic_handler]` function has wrong type
--> $DIR/panic-handler-bad-signature-3.rs:9:1
|
LL | fn panic() -> ! {
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected signature `fn(&PanicInfo<'_>) -> _`
found signature `fn() -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,13 @@
// compile-flags:-C panic=abort
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(info: &PanicInfo<'static>) -> !
//~^ #[panic_handler]` function has wrong type [E0308]
{
loop {}
}

View File

@ -0,0 +1,18 @@
error[E0308]: `#[panic_handler]` function has wrong type
--> $DIR/panic-handler-bad-signature-5.rs:9:1
|
LL | fn panic(info: &PanicInfo<'static>) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&PanicInfo<'_>) -> _`
found signature `fn(&PanicInfo<'static>) -> _`
note: the anonymous lifetime as defined here...
--> $DIR/panic-handler-bad-signature-5.rs:9:1
|
LL | fn panic(info: &PanicInfo<'static>) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -17,9 +17,9 @@ extern "C" fn eh_personality() {}
static EH_CATCH_TYPEINFO: u8 = 0;
#[panic_handler]
fn panic_handler() {}
//~^ ERROR return type should be `!`
//~| ERROR function should have one argument
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
unimplemented!();
}
// take a reference to any built-in range
fn take_range(_r: &impl RangeBounds<i8>) {}

View File

@ -1,15 +1,3 @@
error: return type should be `!`
--> $DIR/issue-54505-no-std.rs:20:20
|
LL | fn panic_handler() {}
| ^
error: function should have one argument
--> $DIR/issue-54505-no-std.rs:20:1
|
LL | fn panic_handler() {}
| ^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/issue-54505-no-std.rs:29:16
|
@ -130,6 +118,6 @@ help: consider borrowing here
LL | take_range(&(..=42));
| ++ +
error: aborting due to 8 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -16,8 +16,8 @@ error[E0580]: `main` function has wrong type
LL | fn main(arguments: Vec<String>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn()`
found fn pointer `fn(Vec<String>)`
= note: expected signature `fn()`
found signature `fn(Vec<String>)`
error[E0425]: cannot find function `log` in this scope
--> $DIR/bad-expr-path.rs:4:5

View File

@ -16,8 +16,8 @@ error[E0580]: `main` function has wrong type
LL | fn main(arguments: Vec<String>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
= note: expected fn pointer `fn()`
found fn pointer `fn(Vec<String>)`
= note: expected signature `fn()`
found signature `fn(Vec<String>)`
error[E0425]: cannot find function `log` in this scope
--> $DIR/bad-expr-path2.rs:6:5