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:
parent
0692db1a90
commit
c599761140
48 changed files with 423 additions and 385 deletions
|
@ -11,8 +11,8 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
|
||||||
|
|
||||||
use std::ops::Not;
|
use std::ops::Not;
|
||||||
|
|
||||||
|
use super::check_function_signature;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::require_same_types;
|
|
||||||
|
|
||||||
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
||||||
match tcx.entry_fn(()) {
|
match tcx.entry_fn(()) {
|
||||||
|
@ -162,33 +162,33 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
// now we can take the return type of the given main function
|
// 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 {
|
} else {
|
||||||
// standard () main return type
|
// standard () main return type
|
||||||
expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx));
|
expected_return_type = tcx.types.unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if error {
|
if error {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let se_ty = Ty::new_fn_ptr(
|
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
tcx,
|
[],
|
||||||
expected_return_type.map_bound(|expected_return_type| {
|
expected_return_type,
|
||||||
tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust)
|
false,
|
||||||
}),
|
hir::Unsafety::Normal,
|
||||||
);
|
Abi::Rust,
|
||||||
|
));
|
||||||
|
|
||||||
require_same_types(
|
check_function_signature(
|
||||||
tcx,
|
tcx,
|
||||||
&ObligationCause::new(
|
ObligationCause::new(
|
||||||
main_span,
|
main_span,
|
||||||
main_diagnostics_def_id,
|
main_diagnostics_def_id,
|
||||||
ObligationCauseCode::MainFunctionType,
|
ObligationCauseCode::MainFunctionType,
|
||||||
),
|
),
|
||||||
param_env,
|
main_def_id,
|
||||||
se_ty,
|
expected_sig,
|
||||||
Ty::new_fn_ptr(tcx, main_fnsig),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,27 +247,23 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let se_ty = Ty::new_fn_ptr(
|
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
tcx,
|
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
|
||||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
tcx.types.isize,
|
||||||
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
|
false,
|
||||||
tcx.types.isize,
|
hir::Unsafety::Normal,
|
||||||
false,
|
Abi::Rust,
|
||||||
hir::Unsafety::Normal,
|
));
|
||||||
Abi::Rust,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
require_same_types(
|
check_function_signature(
|
||||||
tcx,
|
tcx,
|
||||||
&ObligationCause::new(
|
ObligationCause::new(
|
||||||
start_span,
|
start_span,
|
||||||
start_def_id,
|
start_def_id,
|
||||||
ObligationCauseCode::StartFunctionType,
|
ObligationCauseCode::StartFunctionType,
|
||||||
),
|
),
|
||||||
ty::ParamEnv::empty(), // start should not have any where bounds.
|
start_def_id.into(),
|
||||||
se_ty,
|
expected_sig,
|
||||||
Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//! Type-checking for the rust-intrinsic and platform-intrinsic
|
//! Type-checking for the rust-intrinsic and platform-intrinsic
|
||||||
//! intrinsics that the compiler exposes.
|
//! intrinsics that the compiler exposes.
|
||||||
|
|
||||||
|
use crate::check::check_function_signature;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
||||||
WrongNumberOfGenericArgumentsToIntrinsic,
|
WrongNumberOfGenericArgumentsToIntrinsic,
|
||||||
};
|
};
|
||||||
use crate::require_same_types;
|
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use rustc_errors::{struct_span_err, DiagnosticMessage};
|
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.types, n_tps, "type")
|
||||||
&& gen_count_ok(own_counts.consts, 0, "const")
|
&& 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 it_def_id = it.owner_id.def_id;
|
||||||
let cause = ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType);
|
check_function_signature(
|
||||||
require_same_types(
|
|
||||||
tcx,
|
tcx,
|
||||||
&cause,
|
ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
|
||||||
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
|
it_def_id.into(),
|
||||||
Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).instantiate_identity()),
|
sig,
|
||||||
fty,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,23 +73,31 @@ pub mod wfcheck;
|
||||||
|
|
||||||
pub use check::check_abi;
|
pub use check::check_abi;
|
||||||
|
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
use check::check_mod_item_types;
|
use check::check_mod_item_types;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
|
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_index::bit_set::BitSet;
|
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::query::Providers;
|
||||||
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::source_map::DUMMY_SP;
|
use rustc_span::source_map::DUMMY_SP;
|
||||||
use rustc_span::symbol::{kw, Ident};
|
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::abi::VariantIdx;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
|
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::errors;
|
||||||
use crate::require_c_abi_if_c_variadic;
|
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 {
|
pub fn potentially_plural_count(count: usize, word: &str) -> String {
|
||||||
format!("{} {}{}", count, word, pluralize!(count))
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -99,7 +99,6 @@ use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
||||||
use rustc_fluent_macro::fluent_messages;
|
use rustc_fluent_macro::fluent_messages;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
|
||||||
use rustc_middle::middle;
|
use rustc_middle::middle;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -107,8 +106,7 @@ use rustc_middle::util;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
use rustc_trait_selection::traits;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt};
|
|
||||||
|
|
||||||
use astconv::{AstConv, OnlySelfBounds};
|
use astconv::{AstConv, OnlySelfBounds};
|
||||||
use bounds::Bounds;
|
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 });
|
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) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
collect::provide(providers);
|
collect::provide(providers);
|
||||||
coherence::provide(providers);
|
coherence::provide(providers);
|
||||||
|
|
|
@ -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_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 =
|
hir_typeck_lossy_provenance_int2ptr =
|
||||||
strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`
|
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
|
.suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use crate::coercion::CoerceMany;
|
use crate::coercion::CoerceMany;
|
||||||
use crate::errors::{
|
|
||||||
LangStartIncorrectNumberArgs, LangStartIncorrectParam, LangStartIncorrectRetTy,
|
|
||||||
};
|
|
||||||
use crate::gather_locals::GatherLocalsVisitor;
|
use crate::gather_locals::GatherLocalsVisitor;
|
||||||
use crate::FnCtxt;
|
use crate::FnCtxt;
|
||||||
use crate::GeneratorTypes;
|
use crate::GeneratorTypes;
|
||||||
|
@ -9,14 +8,15 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
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::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::RegionVariableOrigin;
|
use rustc_infer::infer::RegionVariableOrigin;
|
||||||
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::traits;
|
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
|
/// 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
|
/// 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()
|
if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
|
||||||
&& panic_impl_did == fn_def_id.to_def_id()
|
&& 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() {
|
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
|
gen_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_panic_info_fn(
|
fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {
|
||||||
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`");
|
|
||||||
}
|
|
||||||
|
|
||||||
let DefKind::Fn = tcx.def_kind(fn_id) else {
|
let DefKind::Fn = tcx.def_kind(fn_id) else {
|
||||||
let span = tcx.def_span(fn_id);
|
let span = tcx.def_span(fn_id);
|
||||||
tcx.sess.span_err(span, "should be a function");
|
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);
|
let span = tcx.def_span(fn_id);
|
||||||
tcx.sess.span_err(span, "should have no const parameters");
|
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>(
|
fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: LocalDefId) {
|
||||||
tcx: TyCtxt<'tcx>,
|
// build type `fn(main: fn() -> T, argc: isize, argv: *const *const u8, sigpipe: u8)`
|
||||||
fn_sig: ty::FnSig<'tcx>,
|
|
||||||
decl: &'tcx hir::FnDecl<'tcx>,
|
|
||||||
def_id: LocalDefId,
|
|
||||||
) {
|
|
||||||
let inputs = fn_sig.inputs();
|
|
||||||
|
|
||||||
let arg_count = inputs.len();
|
// make a Ty for the generic on the fn for diagnostics
|
||||||
if arg_count != 4 {
|
// FIXME: make the lang item generic checks check for the right generic *kind*
|
||||||
tcx.sess.emit_err(LangStartIncorrectNumberArgs {
|
// for example `start`'s generic should be a type parameter
|
||||||
params_span: tcx.def_span(def_id),
|
let generics = tcx.generics_of(def_id);
|
||||||
found_param_count: arg_count,
|
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
|
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
// 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
|
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`
|
check_function_signature(
|
||||||
if let Some(&main_arg) = inputs.get(0) {
|
tcx,
|
||||||
// make a Ty for the generic on the fn for diagnostics
|
ObligationCause::new(
|
||||||
// FIXME: make the lang item generic checks check for the right generic *kind*
|
tcx.def_span(def_id),
|
||||||
// for example `start`'s generic should be a type parameter
|
def_id,
|
||||||
let generics = tcx.generics_of(def_id);
|
ObligationCauseCode::LangFunctionType(sym::start),
|
||||||
let fn_generic = generics.param_at(0, tcx);
|
),
|
||||||
let generic_ty = Ty::new_param(tcx, fn_generic.index, fn_generic.name);
|
def_id.into(),
|
||||||
let expected_fn_sig =
|
expected_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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(hir_typeck_lossy_provenance_int2ptr)]
|
#[diag(hir_typeck_lossy_provenance_int2ptr)]
|
||||||
#[help]
|
#[help]
|
||||||
|
|
|
@ -198,6 +198,10 @@ infer_nothing = {""}
|
||||||
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
|
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
|
||||||
infer_oc_closure_selfref = closure/generator type that references itself
|
infer_oc_closure_selfref = closure/generator type that references itself
|
||||||
infer_oc_const_compat = const not compatible with trait
|
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_main_correct_type = `main` function has wrong type
|
||||||
infer_oc_fn_start_correct_type = `#[start]` function has wrong type
|
infer_oc_fn_start_correct_type = `#[start]` function has wrong type
|
||||||
infer_oc_generic = mismatched types
|
infer_oc_generic = mismatched types
|
||||||
|
@ -337,6 +341,7 @@ infer_subtype = ...so that the {$requirement ->
|
||||||
[no_else] `if` missing an `else` returns `()`
|
[no_else] `if` missing an `else` returns `()`
|
||||||
[fn_main_correct_type] `main` function has the correct type
|
[fn_main_correct_type] `main` function has the correct type
|
||||||
[fn_start_correct_type] `#[start]` 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
|
[intrinsic_correct_type] intrinsic has the correct type
|
||||||
[method_correct_type] method receiver has the correct type
|
[method_correct_type] method receiver has the correct type
|
||||||
*[other] types are compatible
|
*[other] types are compatible
|
||||||
|
@ -350,6 +355,7 @@ infer_subtype_2 = ...so that {$requirement ->
|
||||||
[no_else] `if` missing an `else` returns `()`
|
[no_else] `if` missing an `else` returns `()`
|
||||||
[fn_main_correct_type] `main` function has the correct type
|
[fn_main_correct_type] `main` function has the correct type
|
||||||
[fn_start_correct_type] `#[start]` 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
|
[intrinsic_correct_type] intrinsic has the correct type
|
||||||
[method_correct_type] method receiver has the correct type
|
[method_correct_type] method receiver has the correct type
|
||||||
*[other] types are compatible
|
*[other] types are compatible
|
||||||
|
|
|
@ -1463,6 +1463,14 @@ pub enum ObligationCauseFailureCode {
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
subdiags: Vec<TypeErrorAdditionalDiags>,
|
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")]
|
#[diag(infer_oc_intrinsic_correct_type, code = "E0308")]
|
||||||
IntrinsicCorrectType {
|
IntrinsicCorrectType {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
|
|
@ -2927,6 +2927,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
| IfExpression { .. }
|
| IfExpression { .. }
|
||||||
| LetElse
|
| LetElse
|
||||||
| StartFunctionType
|
| StartFunctionType
|
||||||
|
| LangFunctionType(_)
|
||||||
| IntrinsicType
|
| IntrinsicType
|
||||||
| MethodReceiver => Error0308,
|
| MethodReceiver => Error0308,
|
||||||
|
|
||||||
|
@ -2971,6 +2972,9 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
LetElse => ObligationCauseFailureCode::NoDiverge { span, subdiags },
|
LetElse => ObligationCauseFailureCode::NoDiverge { span, subdiags },
|
||||||
MainFunctionType => ObligationCauseFailureCode::FnMainCorrectType { span },
|
MainFunctionType => ObligationCauseFailureCode::FnMainCorrectType { span },
|
||||||
StartFunctionType => ObligationCauseFailureCode::FnStartCorrectType { span, subdiags },
|
StartFunctionType => ObligationCauseFailureCode::FnStartCorrectType { span, subdiags },
|
||||||
|
&LangFunctionType(lang_item_name) => {
|
||||||
|
ObligationCauseFailureCode::FnLangCorrectType { span, subdiags, lang_item_name }
|
||||||
|
}
|
||||||
IntrinsicType => ObligationCauseFailureCode::IntrinsicCorrectType { span, subdiags },
|
IntrinsicType => ObligationCauseFailureCode::IntrinsicCorrectType { span, subdiags },
|
||||||
MethodReceiver => ObligationCauseFailureCode::MethodCorrectType { span, subdiags },
|
MethodReceiver => ObligationCauseFailureCode::MethodCorrectType { span, subdiags },
|
||||||
|
|
||||||
|
@ -3006,6 +3010,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
|
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
|
||||||
MainFunctionType => "`main` function has the correct type",
|
MainFunctionType => "`main` function has the correct type",
|
||||||
StartFunctionType => "`#[start]` 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",
|
IntrinsicType => "intrinsic has the correct type",
|
||||||
MethodReceiver => "method receiver has the correct type",
|
MethodReceiver => "method receiver has the correct type",
|
||||||
_ => "types are compatible",
|
_ => "types are compatible",
|
||||||
|
@ -3028,6 +3033,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
|
||||||
IfExpressionWithNoElse => "no_else",
|
IfExpressionWithNoElse => "no_else",
|
||||||
MainFunctionType => "fn_main_correct_type",
|
MainFunctionType => "fn_main_correct_type",
|
||||||
StartFunctionType => "fn_start_correct_type",
|
StartFunctionType => "fn_start_correct_type",
|
||||||
|
LangFunctionType(_) => "fn_lang_correct_type",
|
||||||
IntrinsicType => "intrinsic_correct_type",
|
IntrinsicType => "intrinsic_correct_type",
|
||||||
MethodReceiver => "method_correct_type",
|
MethodReceiver => "method_correct_type",
|
||||||
_ => "other",
|
_ => "other",
|
||||||
|
|
|
@ -378,6 +378,9 @@ pub enum ObligationCauseCode<'tcx> {
|
||||||
/// `start` has wrong type
|
/// `start` has wrong type
|
||||||
StartFunctionType,
|
StartFunctionType,
|
||||||
|
|
||||||
|
/// language function has wrong type
|
||||||
|
LangFunctionType(Symbol),
|
||||||
|
|
||||||
/// Intrinsic has wrong type
|
/// Intrinsic has wrong type
|
||||||
IntrinsicType,
|
IntrinsicType,
|
||||||
|
|
||||||
|
|
|
@ -2711,6 +2711,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
| ObligationCauseCode::IfExpressionWithNoElse
|
| ObligationCauseCode::IfExpressionWithNoElse
|
||||||
| ObligationCauseCode::MainFunctionType
|
| ObligationCauseCode::MainFunctionType
|
||||||
| ObligationCauseCode::StartFunctionType
|
| ObligationCauseCode::StartFunctionType
|
||||||
|
| ObligationCauseCode::LangFunctionType(_)
|
||||||
| ObligationCauseCode::IntrinsicType
|
| ObligationCauseCode::IntrinsicType
|
||||||
| ObligationCauseCode::MethodReceiver
|
| ObligationCauseCode::MethodReceiver
|
||||||
| ObligationCauseCode::ReturnNoExpression
|
| ObligationCauseCode::ReturnNoExpression
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
|
LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))`
|
found signature `fn(for<'a> fn(&'a ()))`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern {}
|
||||||
|
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
|
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
|
40+2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-92157.rs:11:1
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
|
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: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
|
||||||
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
|
found signature `fn(fn() -> T, isize, *const *const u8) -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
2
tests/ui/entry-point/auxiliary/bad_main_functions.rs
Normal file
2
tests/ui/entry-point/auxiliary/bad_main_functions.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub fn boilerplate(x: u8) {}
|
||||||
|
//~^ ERROR: `main` function has wrong type [E0580]
|
|
@ -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;
|
|
@ -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`.
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0308]: intrinsic has wrong type
|
error[E0308]: intrinsic has wrong type
|
||||||
--> $DIR/E0308.rs:6:5
|
--> $DIR/E0308.rs:6:20
|
||||||
|
|
|
|
||||||
LL | fn size_of<T>();
|
LL | fn size_of<T>();
|
||||||
| ^^^^^^^^^^^^^^^^ expected `()`, found `usize`
|
| ^ expected `usize`, found `()`
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `extern "rust-intrinsic" fn()`
|
= note: expected signature `extern "rust-intrinsic" fn() -> usize`
|
||||||
found fn pointer `extern "rust-intrinsic" fn() -> usize`
|
found signature `extern "rust-intrinsic" fn()`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
4
tests/ui/extern/extern-main-fn.stderr
vendored
4
tests/ui/extern/extern-main-fn.stderr
vendored
|
@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | extern "C" fn main() {}
|
LL | extern "C" fn main() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn
|
| ^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `extern "C" fn()`
|
found signature `extern "C" fn()`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | fn main(x: isize) { }
|
LL | fn main(x: isize) { }
|
||||||
| ^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `fn(isize)`
|
found signature `fn(isize)`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
LL | fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn(isize, *const *const u8) -> _`
|
= note: expected signature `fn(isize, *const *const u8) -> _`
|
||||||
found fn pointer `fn(isize, *const *const u8, *const u8) -> _`
|
found signature `fn(isize, *const *const u8, *const u8) -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:75:38
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:89:52
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:82:52
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize {
|
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`
|
= note: expected signature `fn(fn() -> _, _, *const *const u8, _) -> _`
|
||||||
|
|
found signature `fn(fn() -> _, _, *const *const usize, _) -> _`
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
|
||||||
| ~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -1,13 +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:61:20
|
--> $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 {
|
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`
|
= note: expected signature `fn(fn() -> _, _, _, _) -> _`
|
||||||
|
|
found signature `fn(fn(i32) -> _, _, _, _) -> _`
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
|
||||||
| ~~~~~~~~~
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:68:20
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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`
|
= note: expected signature `fn(fn() -> T, _, _, _) -> _`
|
||||||
|
|
found signature `fn(fn() -> u16, _, _, _) -> _`
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
|
||||||
| ~~~~~~~~~
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:54:20
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:15:1
|
||||||
|
|
|
|
||||||
LL | fn start<T>() -> isize {
|
LL | fn start<T>() -> isize {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: the `start` lang item should have four parameters, but found 0
|
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
|
||||||
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
|
found signature `fn() -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:29:84
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:22:1
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
|
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: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
|
||||||
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
|
found signature `fn(fn() -> T, isize, *const *const u8) -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -13,33 +13,33 @@ pub trait Sized {}
|
||||||
#[cfg(missing_all_args)]
|
#[cfg(missing_all_args)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>() -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(missing_sigpipe_arg)]
|
#[cfg(missing_sigpipe_arg)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(missing_ret)]
|
#[cfg(missing_ret)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
|
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)]
|
#[cfg(start_ret)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(too_many_args)]
|
#[cfg(too_many_args)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(
|
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,
|
_main: fn() -> T,
|
||||||
_argc: isize,
|
_argc: isize,
|
||||||
_argv: *const *const u8,
|
_argv: *const *const u8,
|
||||||
|
@ -52,49 +52,49 @@ fn start<T>(
|
||||||
#[cfg(main_ty)]
|
#[cfg(main_ty)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(main_args)]
|
#[cfg(main_args)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(main_ret)]
|
#[cfg(main_ret)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(argc)]
|
#[cfg(argc)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(argv_inner_ptr)]
|
#[cfg(argv_inner_ptr)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(argv)]
|
#[cfg(argv)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(sigpipe)]
|
#[cfg(sigpipe)]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize {
|
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
|
100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:96:80
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:34:87
|
||||||
|
|
|
|
||||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 {
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -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
|
--> $DIR/start_lang_item_args.rs:41:1
|
||||||
|
|
|
|
||||||
LL | / fn start<T>(
|
LL | / fn start<T>(
|
||||||
|
@ -8,10 +8,11 @@ LL | | _argc: isize,
|
||||||
... |
|
... |
|
||||||
LL | | _extra_arg: (),
|
LL | | _extra_arg: (),
|
||||||
LL | | ) -> isize {
|
LL | | ) -> isize {
|
||||||
| |__________^
|
| |__________^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: the `start` lang item should have four parameters, but found 5
|
= note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _`
|
||||||
= note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
|
found signature `fn(fn() -> T, isize, *const *const u8, u8, ()) -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | fn main(foo: S) {
|
LL | fn main(foo: S) {
|
||||||
| ^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `fn(S)`
|
found signature `fn(S)`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,5 @@
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(
|
fn panic(info: PanicInfo) -> () {}
|
||||||
info: PanicInfo, //~ ERROR argument should be `&PanicInfo`
|
//~^ `#[panic_handler]` function has wrong type [E0308]
|
||||||
) -> () //~ ERROR return type should be `!`
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
error: return type should be `!`
|
error[E0308]: `#[panic_handler]` function has wrong type
|
||||||
--> $DIR/panic-handler-bad-signature-1.rs:11:6
|
--> $DIR/panic-handler-bad-signature-1.rs:9:16
|
||||||
|
|
|
|
||||||
LL | ) -> ()
|
LL | fn panic(info: PanicInfo) -> () {}
|
||||||
| ^^
|
| ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>`
|
||||||
|
|
||||||
error: argument should be `&PanicInfo`
|
|
||||||
--> $DIR/panic-handler-bad-signature-1.rs:10:11
|
|
||||||
|
|
|
|
||||||
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`.
|
||||||
|
|
|
@ -6,9 +6,8 @@
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(
|
fn panic(info: &'static PanicInfo) -> !
|
||||||
info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo`
|
//~^ #[panic_handler]` function has wrong type [E0308]
|
||||||
) -> !
|
|
||||||
{
|
{
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
error: argument should be `&PanicInfo`
|
error[E0308]: `#[panic_handler]` function has wrong type
|
||||||
--> $DIR/panic-handler-bad-signature-2.rs:10:11
|
--> $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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic() -> ! { //~ ERROR function should have one argument
|
fn panic() -> ! { //~ #[panic_handler]` function has wrong type [E0308]
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/panic-handler-bad-signature-3.rs:9:1
|
||||||
|
|
|
|
||||||
LL | fn panic() -> ! {
|
LL | fn panic() -> ! {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
||||||
|
= note: expected signature `fn(&PanicInfo<'_>) -> _`
|
||||||
|
found signature `fn() -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
13
tests/ui/panic-handler/panic-handler-bad-signature-5.rs
Normal file
13
tests/ui/panic-handler/panic-handler-bad-signature-5.rs
Normal 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 {}
|
||||||
|
}
|
18
tests/ui/panic-handler/panic-handler-bad-signature-5.stderr
Normal file
18
tests/ui/panic-handler/panic-handler-bad-signature-5.stderr
Normal 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`.
|
|
@ -17,9 +17,9 @@ extern "C" fn eh_personality() {}
|
||||||
static EH_CATCH_TYPEINFO: u8 = 0;
|
static EH_CATCH_TYPEINFO: u8 = 0;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler() {}
|
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
|
||||||
//~^ ERROR return type should be `!`
|
unimplemented!();
|
||||||
//~| ERROR function should have one argument
|
}
|
||||||
|
|
||||||
// take a reference to any built-in range
|
// take a reference to any built-in range
|
||||||
fn take_range(_r: &impl RangeBounds<i8>) {}
|
fn take_range(_r: &impl RangeBounds<i8>) {}
|
||||||
|
|
|
@ -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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-54505-no-std.rs:29:16
|
--> $DIR/issue-54505-no-std.rs:29:16
|
||||||
|
|
|
|
||||||
|
@ -130,6 +118,6 @@ help: consider borrowing here
|
||||||
LL | take_range(&(..=42));
|
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`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -16,8 +16,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | fn main(arguments: Vec<String>) {
|
LL | fn main(arguments: Vec<String>) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `fn(Vec<String>)`
|
found signature `fn(Vec<String>)`
|
||||||
|
|
||||||
error[E0425]: cannot find function `log` in this scope
|
error[E0425]: cannot find function `log` in this scope
|
||||||
--> $DIR/bad-expr-path.rs:4:5
|
--> $DIR/bad-expr-path.rs:4:5
|
||||||
|
|
|
@ -16,8 +16,8 @@ error[E0580]: `main` function has wrong type
|
||||||
LL | fn main(arguments: Vec<String>) {
|
LL | fn main(arguments: Vec<String>) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn()`
|
= note: expected signature `fn()`
|
||||||
found fn pointer `fn(Vec<String>)`
|
found signature `fn(Vec<String>)`
|
||||||
|
|
||||||
error[E0425]: cannot find function `log` in this scope
|
error[E0425]: cannot find function `log` in this scope
|
||||||
--> $DIR/bad-expr-path2.rs:6:5
|
--> $DIR/bad-expr-path2.rs:6:5
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue