Skip to content

Commit 9a206a7

Browse files
committed
Improve the help message for an invalid calling convention
1 parent 89e4e1f commit 9a206a7

File tree

17 files changed

+300
-214
lines changed

17 files changed

+300
-214
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4110,6 +4110,7 @@ version = "0.0.0"
41104110
dependencies = [
41114111
"bitflags",
41124112
"rustc_data_structures",
4113+
"rustc_feature",
41134114
"rustc_index",
41144115
"rustc_macros",
41154116
"rustc_serialize",

compiler/rustc_ast_lowering/src/errors.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,28 @@ impl AddToDiagnostic for UseAngleBrackets {
2929
}
3030

3131
#[derive(Diagnostic)]
32-
#[help]
3332
#[diag(ast_lowering::invalid_abi, code = "E0703")]
33+
#[note]
3434
pub struct InvalidAbi {
3535
#[primary_span]
3636
#[label]
3737
pub span: Span,
3838
pub abi: Symbol,
39-
pub valid_abis: String,
39+
pub command: String,
40+
#[subdiagnostic]
41+
pub suggestion: Option<InvalidAbiSuggestion>,
42+
}
43+
44+
#[derive(Subdiagnostic)]
45+
#[suggestion(
46+
ast_lowering::invalid_abi_suggestion,
47+
code = "{suggestion}",
48+
applicability = "maybe-incorrect"
49+
)]
50+
pub struct InvalidAbiSuggestion {
51+
#[primary_span]
52+
pub span: Span,
53+
pub suggestion: String,
4054
}
4155

4256
#[derive(Diagnostic, Clone, Copy)]

compiler/rustc_ast_lowering/src/item.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::errors::{InvalidAbi, MisplacedRelaxTraitBound};
1+
use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
22
use super::ResolverAstLoweringExt;
33
use super::{Arena, AstOwner, ImplTraitContext, ImplTraitPosition};
44
use super::{FnDeclKind, LoweringContext, ParamMode};
@@ -14,9 +14,10 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
1414
use rustc_hir::PredicateOrigin;
1515
use rustc_index::vec::{Idx, IndexVec};
1616
use rustc_middle::ty::{DefIdTree, ResolverAstLowering, TyCtxt};
17+
use rustc_span::lev_distance::find_best_match_for_name;
1718
use rustc_span::source_map::DesugaringKind;
1819
use rustc_span::symbol::{kw, sym, Ident};
19-
use rustc_span::Span;
20+
use rustc_span::{Span, Symbol};
2021
use rustc_target::spec::abi;
2122
use smallvec::{smallvec, SmallVec};
2223

@@ -1280,10 +1281,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
12801281
}
12811282

12821283
fn error_on_invalid_abi(&self, abi: StrLit) {
1284+
let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
1285+
.iter()
1286+
.map(|s| Symbol::intern(s))
1287+
.collect::<Vec<_>>();
1288+
let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
12831289
self.tcx.sess.emit_err(InvalidAbi {
1290+
abi: abi.symbol_unescaped,
12841291
span: abi.span,
1285-
abi: abi.symbol,
1286-
valid_abis: abi::all_names().join(", "),
1292+
suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
1293+
span: abi.span,
1294+
suggestion: format!("\"{suggested_name}\""),
1295+
}),
1296+
command: "rustc --print=calling-conventions".to_string(),
12871297
});
12881298
}
12891299

compiler/rustc_ast_passes/src/feature_gate.rs

+18-202
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
44
use rustc_ast::{PatKind, RangeEnd, VariantData};
55
use rustc_errors::{struct_span_err, Applicability, StashKey};
6-
use rustc_feature::Features;
7-
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
8-
use rustc_session::parse::{feature_err, feature_warn};
6+
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
7+
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
98
use rustc_session::Session;
109
use rustc_span::source_map::Spanned;
1110
use rustc_span::symbol::sym;
1211
use rustc_span::Span;
12+
use rustc_target::spec::abi;
1313

1414
macro_rules! gate_feature_fn {
1515
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
@@ -84,210 +84,26 @@ impl<'a> PostExpansionVisitor<'a> {
8484
}
8585
}
8686

87-
match symbol_unescaped.as_str() {
88-
// Stable
89-
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
90-
| "system" => {}
91-
"rust-intrinsic" => {
92-
gate_feature_post!(&self, intrinsics, span, "intrinsics are subject to change");
93-
}
94-
"platform-intrinsic" => {
95-
gate_feature_post!(
96-
&self,
97-
platform_intrinsics,
98-
span,
99-
"platform intrinsics are experimental and possibly buggy"
100-
);
101-
}
102-
"vectorcall" => {
103-
gate_feature_post!(
104-
&self,
105-
abi_vectorcall,
106-
span,
107-
"vectorcall is experimental and subject to change"
108-
);
109-
}
110-
"thiscall" => {
111-
gate_feature_post!(
112-
&self,
113-
abi_thiscall,
114-
span,
115-
"thiscall is experimental and subject to change"
116-
);
117-
}
118-
"rust-call" => {
119-
gate_feature_post!(
120-
&self,
121-
unboxed_closures,
122-
span,
123-
"rust-call ABI is subject to change"
124-
);
125-
}
126-
"rust-cold" => {
127-
gate_feature_post!(
128-
&self,
129-
rust_cold_cc,
130-
span,
131-
"rust-cold is experimental and subject to change"
132-
);
133-
}
134-
"ptx-kernel" => {
135-
gate_feature_post!(
136-
&self,
137-
abi_ptx,
138-
span,
139-
"PTX ABIs are experimental and subject to change"
140-
);
141-
}
142-
"unadjusted" => {
143-
gate_feature_post!(
144-
&self,
145-
abi_unadjusted,
146-
span,
147-
"unadjusted ABI is an implementation detail and perma-unstable"
148-
);
149-
}
150-
"msp430-interrupt" => {
151-
gate_feature_post!(
152-
&self,
153-
abi_msp430_interrupt,
154-
span,
155-
"msp430-interrupt ABI is experimental and subject to change"
156-
);
157-
}
158-
"x86-interrupt" => {
159-
gate_feature_post!(
160-
&self,
161-
abi_x86_interrupt,
162-
span,
163-
"x86-interrupt ABI is experimental and subject to change"
164-
);
165-
}
166-
"amdgpu-kernel" => {
167-
gate_feature_post!(
168-
&self,
169-
abi_amdgpu_kernel,
170-
span,
171-
"amdgpu-kernel ABI is experimental and subject to change"
172-
);
173-
}
174-
"avr-interrupt" | "avr-non-blocking-interrupt" => {
175-
gate_feature_post!(
176-
&self,
177-
abi_avr_interrupt,
178-
span,
179-
"avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change"
180-
);
181-
}
182-
"efiapi" => {
183-
gate_feature_post!(
184-
&self,
185-
abi_efiapi,
186-
span,
187-
"efiapi ABI is experimental and subject to change"
188-
);
189-
}
190-
"C-cmse-nonsecure-call" => {
191-
gate_feature_post!(
192-
&self,
193-
abi_c_cmse_nonsecure_call,
194-
span,
195-
"C-cmse-nonsecure-call ABI is experimental and subject to change"
196-
);
197-
}
198-
"C-unwind" => {
199-
gate_feature_post!(
200-
&self,
201-
c_unwind,
202-
span,
203-
"C-unwind ABI is experimental and subject to change"
204-
);
205-
}
206-
"stdcall-unwind" => {
207-
gate_feature_post!(
208-
&self,
209-
c_unwind,
87+
match abi::is_enabled(&self.features, span, symbol_unescaped.as_str()) {
88+
Ok(()) => (),
89+
Err(abi::AbiDisabled::Unstable { feature, explain }) => {
90+
feature_err_issue(
91+
&self.sess.parse_sess,
92+
feature,
21093
span,
211-
"stdcall-unwind ABI is experimental and subject to change"
212-
);
213-
}
214-
"system-unwind" => {
215-
gate_feature_post!(
216-
&self,
217-
c_unwind,
218-
span,
219-
"system-unwind ABI is experimental and subject to change"
220-
);
221-
}
222-
"thiscall-unwind" => {
223-
gate_feature_post!(
224-
&self,
225-
c_unwind,
226-
span,
227-
"thiscall-unwind ABI is experimental and subject to change"
228-
);
229-
}
230-
"cdecl-unwind" => {
231-
gate_feature_post!(
232-
&self,
233-
c_unwind,
234-
span,
235-
"cdecl-unwind ABI is experimental and subject to change"
236-
);
237-
}
238-
"fastcall-unwind" => {
239-
gate_feature_post!(
240-
&self,
241-
c_unwind,
242-
span,
243-
"fastcall-unwind ABI is experimental and subject to change"
244-
);
245-
}
246-
"vectorcall-unwind" => {
247-
gate_feature_post!(
248-
&self,
249-
c_unwind,
250-
span,
251-
"vectorcall-unwind ABI is experimental and subject to change"
252-
);
253-
}
254-
"aapcs-unwind" => {
255-
gate_feature_post!(
256-
&self,
257-
c_unwind,
258-
span,
259-
"aapcs-unwind ABI is experimental and subject to change"
260-
);
261-
}
262-
"win64-unwind" => {
263-
gate_feature_post!(
264-
&self,
265-
c_unwind,
266-
span,
267-
"win64-unwind ABI is experimental and subject to change"
268-
);
269-
}
270-
"sysv64-unwind" => {
271-
gate_feature_post!(
272-
&self,
273-
c_unwind,
274-
span,
275-
"sysv64-unwind ABI is experimental and subject to change"
276-
);
277-
}
278-
"wasm" => {
279-
gate_feature_post!(
280-
&self,
281-
wasm_abi,
282-
span,
283-
"wasm ABI is experimental and subject to change"
284-
);
94+
GateIssue::Language,
95+
explain,
96+
)
97+
.emit();
28598
}
286-
abi => {
99+
Err(abi::AbiDisabled::Unrecognized) => {
287100
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
288101
self.sess.parse_sess.span_diagnostic.delay_span_bug(
289102
span,
290-
&format!("unrecognized ABI not caught in lowering: {}", abi),
103+
&format!(
104+
"unrecognized ABI not caught in lowering: {}",
105+
symbol_unescaped.as_str()
106+
),
291107
);
292108
}
293109
}

compiler/rustc_driver/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,11 @@ fn print_crate_info(
742742
println!("{}", cfg);
743743
}
744744
}
745+
CallingConventions => {
746+
let mut calling_conventions = rustc_target::spec::abi::all_names();
747+
calling_conventions.sort_unstable();
748+
println!("{}", calling_conventions.join("\n"));
749+
}
745750
RelocationModels
746751
| CodeModels
747752
| TlsModels

compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ ast_lowering_use_angle_brackets = use angle brackets instead
77
ast_lowering_invalid_abi =
88
invalid ABI: found `{$abi}`
99
.label = invalid ABI
10-
.help = valid ABIs: {$valid_abis}
10+
.note = invoke `{$command}` for a full list of supported calling conventions.
11+
12+
ast_lowering_invalid_abi_suggestion = did you mean
1113
1214
ast_lowering_assoc_ty_parentheses =
1315
parenthesized generic arguments cannot be used in associated type constraints

compiler/rustc_session/src/config.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ pub enum PrintRequest {
538538
TargetLibdir,
539539
CrateName,
540540
Cfg,
541+
CallingConventions,
541542
TargetList,
542543
TargetCPUs,
543544
TargetFeatures,
@@ -1354,8 +1355,8 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
13541355
"",
13551356
"print",
13561357
"Compiler information to print on stdout",
1357-
"[crate-name|file-names|sysroot|target-libdir|cfg|target-list|\
1358-
target-cpus|target-features|relocation-models|code-models|\
1358+
"[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
1359+
target-list|target-cpus|target-features|relocation-models|code-models|\
13591360
tls-models|target-spec-json|native-static-libs|stack-protector-strategies|\
13601361
link-args]",
13611362
),
@@ -1794,6 +1795,7 @@ fn collect_print_requests(
17941795
"sysroot" => PrintRequest::Sysroot,
17951796
"target-libdir" => PrintRequest::TargetLibdir,
17961797
"cfg" => PrintRequest::Cfg,
1798+
"calling-conventions" => PrintRequest::CallingConventions,
17971799
"target-list" => PrintRequest::TargetList,
17981800
"target-cpus" => PrintRequest::TargetCPUs,
17991801
"target-features" => PrintRequest::TargetFeatures,

compiler/rustc_target/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ bitflags = "1.2.1"
88
tracing = "0.1"
99
serde_json = "1.0.59"
1010
rustc_data_structures = { path = "../rustc_data_structures" }
11+
rustc_feature = { path = "../rustc_feature" }
12+
rustc_index = { path = "../rustc_index" }
1113
rustc_macros = { path = "../rustc_macros" }
1214
rustc_serialize = { path = "../rustc_serialize" }
1315
rustc_span = { path = "../rustc_span" }
14-
rustc_index = { path = "../rustc_index" }

0 commit comments

Comments
 (0)