Improve the help message for an invalid calling convention
This commit is contained in:
parent
89e4e1f1b3
commit
9a206a78eb
17 changed files with 300 additions and 214 deletions
|
@ -4110,6 +4110,7 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
|
"rustc_feature",
|
||||||
"rustc_index",
|
"rustc_index",
|
||||||
"rustc_macros",
|
"rustc_macros",
|
||||||
"rustc_serialize",
|
"rustc_serialize",
|
||||||
|
|
|
@ -29,14 +29,28 @@ impl AddToDiagnostic for UseAngleBrackets {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[help]
|
|
||||||
#[diag(ast_lowering::invalid_abi, code = "E0703")]
|
#[diag(ast_lowering::invalid_abi, code = "E0703")]
|
||||||
|
#[note]
|
||||||
pub struct InvalidAbi {
|
pub struct InvalidAbi {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub abi: Symbol,
|
pub abi: Symbol,
|
||||||
pub valid_abis: String,
|
pub command: String,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub suggestion: Option<InvalidAbiSuggestion>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[suggestion(
|
||||||
|
ast_lowering::invalid_abi_suggestion,
|
||||||
|
code = "{suggestion}",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub struct InvalidAbiSuggestion {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub suggestion: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic, Clone, Copy)]
|
#[derive(Diagnostic, Clone, Copy)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::errors::{InvalidAbi, MisplacedRelaxTraitBound};
|
use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
|
||||||
use super::ResolverAstLoweringExt;
|
use super::ResolverAstLoweringExt;
|
||||||
use super::{Arena, AstOwner, ImplTraitContext, ImplTraitPosition};
|
use super::{Arena, AstOwner, ImplTraitContext, ImplTraitPosition};
|
||||||
use super::{FnDeclKind, LoweringContext, ParamMode};
|
use super::{FnDeclKind, LoweringContext, ParamMode};
|
||||||
|
@ -14,9 +14,10 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||||
use rustc_hir::PredicateOrigin;
|
use rustc_hir::PredicateOrigin;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_middle::ty::{DefIdTree, ResolverAstLowering, TyCtxt};
|
use rustc_middle::ty::{DefIdTree, ResolverAstLowering, TyCtxt};
|
||||||
|
use rustc_span::lev_distance::find_best_match_for_name;
|
||||||
use rustc_span::source_map::DesugaringKind;
|
use rustc_span::source_map::DesugaringKind;
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, Symbol};
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
|
@ -1280,10 +1281,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_on_invalid_abi(&self, abi: StrLit) {
|
fn error_on_invalid_abi(&self, abi: StrLit) {
|
||||||
|
let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
|
||||||
|
.iter()
|
||||||
|
.map(|s| Symbol::intern(s))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
|
||||||
self.tcx.sess.emit_err(InvalidAbi {
|
self.tcx.sess.emit_err(InvalidAbi {
|
||||||
|
abi: abi.symbol_unescaped,
|
||||||
span: abi.span,
|
span: abi.span,
|
||||||
abi: abi.symbol,
|
suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
|
||||||
valid_abis: abi::all_names().join(", "),
|
span: abi.span,
|
||||||
|
suggestion: format!("\"{suggested_name}\""),
|
||||||
|
}),
|
||||||
|
command: "rustc --print=calling-conventions".to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||||
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
|
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
|
||||||
use rustc_ast::{PatKind, RangeEnd, VariantData};
|
use rustc_ast::{PatKind, RangeEnd, VariantData};
|
||||||
use rustc_errors::{struct_span_err, Applicability, StashKey};
|
use rustc_errors::{struct_span_err, Applicability, StashKey};
|
||||||
use rustc_feature::Features;
|
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
|
||||||
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
|
||||||
use rustc_session::parse::{feature_err, feature_warn};
|
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use rustc_target::spec::abi;
|
||||||
|
|
||||||
macro_rules! gate_feature_fn {
|
macro_rules! gate_feature_fn {
|
||||||
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
|
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
|
||||||
|
@ -84,210 +84,26 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match symbol_unescaped.as_str() {
|
match abi::is_enabled(&self.features, span, symbol_unescaped.as_str()) {
|
||||||
// Stable
|
Ok(()) => (),
|
||||||
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
Err(abi::AbiDisabled::Unstable { feature, explain }) => {
|
||||||
| "system" => {}
|
feature_err_issue(
|
||||||
"rust-intrinsic" => {
|
&self.sess.parse_sess,
|
||||||
gate_feature_post!(&self, intrinsics, span, "intrinsics are subject to change");
|
feature,
|
||||||
}
|
|
||||||
"platform-intrinsic" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
platform_intrinsics,
|
|
||||||
span,
|
span,
|
||||||
"platform intrinsics are experimental and possibly buggy"
|
GateIssue::Language,
|
||||||
);
|
explain,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
}
|
}
|
||||||
"vectorcall" => {
|
Err(abi::AbiDisabled::Unrecognized) => {
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_vectorcall,
|
|
||||||
span,
|
|
||||||
"vectorcall is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"thiscall" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_thiscall,
|
|
||||||
span,
|
|
||||||
"thiscall is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"rust-call" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
unboxed_closures,
|
|
||||||
span,
|
|
||||||
"rust-call ABI is subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"rust-cold" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
rust_cold_cc,
|
|
||||||
span,
|
|
||||||
"rust-cold is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"ptx-kernel" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_ptx,
|
|
||||||
span,
|
|
||||||
"PTX ABIs are experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"unadjusted" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_unadjusted,
|
|
||||||
span,
|
|
||||||
"unadjusted ABI is an implementation detail and perma-unstable"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"msp430-interrupt" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_msp430_interrupt,
|
|
||||||
span,
|
|
||||||
"msp430-interrupt ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"x86-interrupt" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_x86_interrupt,
|
|
||||||
span,
|
|
||||||
"x86-interrupt ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"amdgpu-kernel" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_amdgpu_kernel,
|
|
||||||
span,
|
|
||||||
"amdgpu-kernel ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"avr-interrupt" | "avr-non-blocking-interrupt" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_avr_interrupt,
|
|
||||||
span,
|
|
||||||
"avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"efiapi" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_efiapi,
|
|
||||||
span,
|
|
||||||
"efiapi ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"C-cmse-nonsecure-call" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
abi_c_cmse_nonsecure_call,
|
|
||||||
span,
|
|
||||||
"C-cmse-nonsecure-call ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"C-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"C-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"stdcall-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"stdcall-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"system-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"system-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"thiscall-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"thiscall-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"cdecl-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"cdecl-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"fastcall-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"fastcall-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"vectorcall-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"vectorcall-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"aapcs-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"aapcs-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"win64-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"win64-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"sysv64-unwind" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
c_unwind,
|
|
||||||
span,
|
|
||||||
"sysv64-unwind ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"wasm" => {
|
|
||||||
gate_feature_post!(
|
|
||||||
&self,
|
|
||||||
wasm_abi,
|
|
||||||
span,
|
|
||||||
"wasm ABI is experimental and subject to change"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
abi => {
|
|
||||||
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
|
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
|
||||||
self.sess.parse_sess.span_diagnostic.delay_span_bug(
|
self.sess.parse_sess.span_diagnostic.delay_span_bug(
|
||||||
span,
|
span,
|
||||||
&format!("unrecognized ABI not caught in lowering: {}", abi),
|
&format!(
|
||||||
|
"unrecognized ABI not caught in lowering: {}",
|
||||||
|
symbol_unescaped.as_str()
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -742,6 +742,11 @@ fn print_crate_info(
|
||||||
println!("{}", cfg);
|
println!("{}", cfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CallingConventions => {
|
||||||
|
let mut calling_conventions = rustc_target::spec::abi::all_names();
|
||||||
|
calling_conventions.sort_unstable();
|
||||||
|
println!("{}", calling_conventions.join("\n"));
|
||||||
|
}
|
||||||
RelocationModels
|
RelocationModels
|
||||||
| CodeModels
|
| CodeModels
|
||||||
| TlsModels
|
| TlsModels
|
||||||
|
|
|
@ -7,7 +7,9 @@ ast_lowering_use_angle_brackets = use angle brackets instead
|
||||||
ast_lowering_invalid_abi =
|
ast_lowering_invalid_abi =
|
||||||
invalid ABI: found `{$abi}`
|
invalid ABI: found `{$abi}`
|
||||||
.label = invalid ABI
|
.label = invalid ABI
|
||||||
.help = valid ABIs: {$valid_abis}
|
.note = invoke `{$command}` for a full list of supported calling conventions.
|
||||||
|
|
||||||
|
ast_lowering_invalid_abi_suggestion = did you mean
|
||||||
|
|
||||||
ast_lowering_assoc_ty_parentheses =
|
ast_lowering_assoc_ty_parentheses =
|
||||||
parenthesized generic arguments cannot be used in associated type constraints
|
parenthesized generic arguments cannot be used in associated type constraints
|
||||||
|
|
|
@ -538,6 +538,7 @@ pub enum PrintRequest {
|
||||||
TargetLibdir,
|
TargetLibdir,
|
||||||
CrateName,
|
CrateName,
|
||||||
Cfg,
|
Cfg,
|
||||||
|
CallingConventions,
|
||||||
TargetList,
|
TargetList,
|
||||||
TargetCPUs,
|
TargetCPUs,
|
||||||
TargetFeatures,
|
TargetFeatures,
|
||||||
|
@ -1354,8 +1355,8 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
||||||
"",
|
"",
|
||||||
"print",
|
"print",
|
||||||
"Compiler information to print on stdout",
|
"Compiler information to print on stdout",
|
||||||
"[crate-name|file-names|sysroot|target-libdir|cfg|target-list|\
|
"[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
|
||||||
target-cpus|target-features|relocation-models|code-models|\
|
target-list|target-cpus|target-features|relocation-models|code-models|\
|
||||||
tls-models|target-spec-json|native-static-libs|stack-protector-strategies|\
|
tls-models|target-spec-json|native-static-libs|stack-protector-strategies|\
|
||||||
link-args]",
|
link-args]",
|
||||||
),
|
),
|
||||||
|
@ -1794,6 +1795,7 @@ fn collect_print_requests(
|
||||||
"sysroot" => PrintRequest::Sysroot,
|
"sysroot" => PrintRequest::Sysroot,
|
||||||
"target-libdir" => PrintRequest::TargetLibdir,
|
"target-libdir" => PrintRequest::TargetLibdir,
|
||||||
"cfg" => PrintRequest::Cfg,
|
"cfg" => PrintRequest::Cfg,
|
||||||
|
"calling-conventions" => PrintRequest::CallingConventions,
|
||||||
"target-list" => PrintRequest::TargetList,
|
"target-list" => PrintRequest::TargetList,
|
||||||
"target-cpus" => PrintRequest::TargetCPUs,
|
"target-cpus" => PrintRequest::TargetCPUs,
|
||||||
"target-features" => PrintRequest::TargetFeatures,
|
"target-features" => PrintRequest::TargetFeatures,
|
||||||
|
|
|
@ -8,7 +8,8 @@ bitflags = "1.2.1"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
serde_json = "1.0.59"
|
serde_json = "1.0.59"
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
|
rustc_feature = { path = "../rustc_feature" }
|
||||||
|
rustc_index = { path = "../rustc_index" }
|
||||||
rustc_macros = { path = "../rustc_macros" }
|
rustc_macros = { path = "../rustc_macros" }
|
||||||
rustc_serialize = { path = "../rustc_serialize" }
|
rustc_serialize = { path = "../rustc_serialize" }
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
rustc_index = { path = "../rustc_index" }
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_macros::HashStable_Generic;
|
use rustc_macros::HashStable_Generic;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -94,6 +96,192 @@ pub fn all_names() -> Vec<&'static str> {
|
||||||
AbiDatas.iter().map(|d| d.name).collect()
|
AbiDatas.iter().map(|d| d.name).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enabled_names(features: &rustc_feature::Features, span: Span) -> Vec<&'static str> {
|
||||||
|
AbiDatas
|
||||||
|
.iter()
|
||||||
|
.map(|d| d.name)
|
||||||
|
.filter(|name| is_enabled(features, span, name).is_ok())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum AbiDisabled {
|
||||||
|
Unstable { feature: Symbol, explain: &'static str },
|
||||||
|
Unrecognized,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gate_feature_post(
|
||||||
|
features: &rustc_feature::Features,
|
||||||
|
feature: Symbol,
|
||||||
|
span: Span,
|
||||||
|
explain: &'static str,
|
||||||
|
) -> Result<(), AbiDisabled> {
|
||||||
|
if !features.enabled(feature) && !span.allows_unstable(feature) {
|
||||||
|
Err(AbiDisabled::Unstable { feature, explain })
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_enabled(
|
||||||
|
features: &rustc_feature::Features,
|
||||||
|
span: Span,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<(), AbiDisabled> {
|
||||||
|
match name {
|
||||||
|
// Stable
|
||||||
|
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
||||||
|
| "system" => Ok(()),
|
||||||
|
"rust-intrinsic" => {
|
||||||
|
gate_feature_post(features, sym::intrinsics, span, "intrinsics are subject to change")
|
||||||
|
}
|
||||||
|
"platform-intrinsic" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::platform_intrinsics,
|
||||||
|
span,
|
||||||
|
"platform intrinsics are experimental and possibly buggy",
|
||||||
|
),
|
||||||
|
"vectorcall" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_vectorcall,
|
||||||
|
span,
|
||||||
|
"vectorcall is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"thiscall" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_thiscall,
|
||||||
|
span,
|
||||||
|
"thiscall is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"rust-call" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::unboxed_closures,
|
||||||
|
span,
|
||||||
|
"rust-call ABI is subject to change",
|
||||||
|
),
|
||||||
|
"rust-cold" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::rust_cold_cc,
|
||||||
|
span,
|
||||||
|
"rust-cold is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"ptx-kernel" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_ptx,
|
||||||
|
span,
|
||||||
|
"PTX ABIs are experimental and subject to change",
|
||||||
|
),
|
||||||
|
"unadjusted" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_unadjusted,
|
||||||
|
span,
|
||||||
|
"unadjusted ABI is an implementation detail and perma-unstable",
|
||||||
|
),
|
||||||
|
"msp430-interrupt" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_msp430_interrupt,
|
||||||
|
span,
|
||||||
|
"msp430-interrupt ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"x86-interrupt" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_x86_interrupt,
|
||||||
|
span,
|
||||||
|
"x86-interrupt ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"amdgpu-kernel" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_amdgpu_kernel,
|
||||||
|
span,
|
||||||
|
"amdgpu-kernel ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"avr-interrupt" | "avr-non-blocking-interrupt" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_avr_interrupt,
|
||||||
|
span,
|
||||||
|
"avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
|
||||||
|
),
|
||||||
|
"efiapi" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_efiapi,
|
||||||
|
span,
|
||||||
|
"efiapi ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"C-cmse-nonsecure-call" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::abi_c_cmse_nonsecure_call,
|
||||||
|
span,
|
||||||
|
"C-cmse-nonsecure-call ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"C-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"C-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"stdcall-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"stdcall-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"system-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"system-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"thiscall-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"thiscall-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"cdecl-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"cdecl-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"fastcall-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"fastcall-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"vectorcall-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"vectorcall-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"aapcs-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"aapcs-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"win64-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"win64-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"sysv64-unwind" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::c_unwind,
|
||||||
|
span,
|
||||||
|
"sysv64-unwind ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
"wasm" => gate_feature_post(
|
||||||
|
features,
|
||||||
|
sym::wasm_abi,
|
||||||
|
span,
|
||||||
|
"wasm ABI is experimental and subject to change",
|
||||||
|
),
|
||||||
|
_ => Err(AbiDisabled::Unrecognized),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Abi {
|
impl Abi {
|
||||||
/// Default ABI chosen for `extern fn` declarations without an explicit ABI.
|
/// Default ABI chosen for `extern fn` declarations without an explicit ABI.
|
||||||
pub const FALLBACK: Abi = Abi::C { unwind: false };
|
pub const FALLBACK: Abi = Abi::C { unwind: false };
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
-include ../tools.mk
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(RUSTC) --print calling-conventions
|
6
src/test/ui/abi/abi-typo-unstable.rs
Normal file
6
src/test/ui/abi/abi-typo-unstable.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// rust-intrinsic is unstable and not enabled, so it should not be suggested as a fix
|
||||||
|
extern "rust-intrinsec" fn rust_intrinsic() {} //~ ERROR invalid ABI
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
rust_intrinsic();
|
||||||
|
}
|
11
src/test/ui/abi/abi-typo-unstable.stderr
Normal file
11
src/test/ui/abi/abi-typo-unstable.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0703]: invalid ABI: found `rust-intrinsec`
|
||||||
|
--> $DIR/abi-typo-unstable.rs:2:8
|
||||||
|
|
|
||||||
|
LL | extern "rust-intrinsec" fn rust_intrinsic() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ invalid ABI
|
||||||
|
|
|
||||||
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0703`.
|
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
|
||||||
LL | extern "路濫狼á́́" fn foo() {}
|
LL | extern "路濫狼á́́" fn foo() {}
|
||||||
| ^^^^^^^^^ invalid ABI
|
| ^^^^^^^^^ invalid ABI
|
||||||
|
|
|
|
||||||
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
|
||||||
LL | "invalid-ab_isize"
|
LL | "invalid-ab_isize"
|
||||||
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
||||||
|
|
|
|
||||||
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
6
src/test/ui/suggestions/abi-typo.fixed
Normal file
6
src/test/ui/suggestions/abi-typo.fixed
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// run-rustfix
|
||||||
|
extern "cdecl" fn cdedl() {} //~ ERROR invalid ABI
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
cdedl();
|
||||||
|
}
|
6
src/test/ui/suggestions/abi-typo.rs
Normal file
6
src/test/ui/suggestions/abi-typo.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// run-rustfix
|
||||||
|
extern "cdedl" fn cdedl() {} //~ ERROR invalid ABI
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
cdedl();
|
||||||
|
}
|
14
src/test/ui/suggestions/abi-typo.stderr
Normal file
14
src/test/ui/suggestions/abi-typo.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0703]: invalid ABI: found `cdedl`
|
||||||
|
--> $DIR/abi-typo.rs:2:8
|
||||||
|
|
|
||||||
|
LL | extern "cdedl" fn cdedl() {}
|
||||||
|
| ^^^^^^^
|
||||||
|
| |
|
||||||
|
| invalid ABI
|
||||||
|
| help: did you mean: `"cdecl"`
|
||||||
|
|
|
||||||
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0703`.
|
Loading…
Add table
Add a link
Reference in a new issue