]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_session/src/errors.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / compiler / rustc_session / src / errors.rs
CommitLineData
f2b60f7d
FG
1use std::num::NonZeroU32;
2
3use crate::cgu_reuse_tracker::CguReuse;
487cf647
FG
4use crate::parse::ParseSess;
5use rustc_ast::token;
6use rustc_ast::util::literal::LitError;
9ffffee4 7use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan};
2b03887a 8use rustc_macros::Diagnostic;
49aad941 9use rustc_span::{BytePos, Span, Symbol};
f2b60f7d
FG
10use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
11
2b03887a
FG
12#[derive(Diagnostic)]
13#[diag(session_incorrect_cgu_reuse_type)]
f2b60f7d
FG
14pub struct IncorrectCguReuseType<'a> {
15 #[primary_span]
16 pub span: Span,
17 pub cgu_user_name: &'a str,
18 pub actual_reuse: CguReuse,
19 pub expected_reuse: CguReuse,
20 pub at_least: u8,
21}
22
2b03887a
FG
23#[derive(Diagnostic)]
24#[diag(session_cgu_not_recorded)]
f2b60f7d
FG
25pub struct CguNotRecorded<'a> {
26 pub cgu_user_name: &'a str,
27 pub cgu_name: &'a str,
28}
29
9ffffee4 30pub struct FeatureGateError {
f2b60f7d 31 pub span: MultiSpan,
9ffffee4
FG
32 pub explain: DiagnosticMessage,
33}
34
35impl<'a, T: EmissionGuarantee> IntoDiagnostic<'a, T> for FeatureGateError {
36 #[track_caller]
37 fn into_diagnostic(
38 self,
39 handler: &'a rustc_errors::Handler,
40 ) -> rustc_errors::DiagnosticBuilder<'a, T> {
41 let mut diag = handler.struct_diagnostic(self.explain);
42 diag.set_span(self.span);
43 diag.code(error_code!(E0658));
44 diag
45 }
f2b60f7d
FG
46}
47
2b03887a
FG
48#[derive(Subdiagnostic)]
49#[note(session_feature_diagnostic_for_issue)]
f2b60f7d
FG
50pub struct FeatureDiagnosticForIssue {
51 pub n: NonZeroU32,
52}
53
2b03887a
FG
54#[derive(Subdiagnostic)]
55#[help(session_feature_diagnostic_help)]
f2b60f7d
FG
56pub struct FeatureDiagnosticHelp {
57 pub feature: Symbol,
58}
59
781aab86
FG
60#[derive(Subdiagnostic)]
61#[help(session_cli_feature_diagnostic_help)]
62pub struct CliFeatureDiagnosticHelp {
63 pub feature: Symbol,
64}
65
2b03887a
FG
66#[derive(Diagnostic)]
67#[diag(session_not_circumvent_feature)]
f2b60f7d
FG
68pub struct NotCircumventFeature;
69
2b03887a
FG
70#[derive(Diagnostic)]
71#[diag(session_linker_plugin_lto_windows_not_supported)]
f2b60f7d
FG
72pub struct LinkerPluginToWindowsNotSupported;
73
2b03887a
FG
74#[derive(Diagnostic)]
75#[diag(session_profile_use_file_does_not_exist)]
f2b60f7d
FG
76pub struct ProfileUseFileDoesNotExist<'a> {
77 pub path: &'a std::path::Path,
78}
79
2b03887a
FG
80#[derive(Diagnostic)]
81#[diag(session_profile_sample_use_file_does_not_exist)]
f2b60f7d
FG
82pub struct ProfileSampleUseFileDoesNotExist<'a> {
83 pub path: &'a std::path::Path,
84}
85
2b03887a
FG
86#[derive(Diagnostic)]
87#[diag(session_target_requires_unwind_tables)]
f2b60f7d
FG
88pub struct TargetRequiresUnwindTables;
89
9ffffee4
FG
90#[derive(Diagnostic)]
91#[diag(session_instrumentation_not_supported)]
92pub struct InstrumentationNotSupported {
93 pub us: String,
94}
95
2b03887a
FG
96#[derive(Diagnostic)]
97#[diag(session_sanitizer_not_supported)]
f2b60f7d
FG
98pub struct SanitizerNotSupported {
99 pub us: String,
100}
101
2b03887a
FG
102#[derive(Diagnostic)]
103#[diag(session_sanitizers_not_supported)]
f2b60f7d
FG
104pub struct SanitizersNotSupported {
105 pub us: String,
106}
107
2b03887a
FG
108#[derive(Diagnostic)]
109#[diag(session_cannot_mix_and_match_sanitizers)]
f2b60f7d
FG
110pub struct CannotMixAndMatchSanitizers {
111 pub first: String,
112 pub second: String,
113}
114
2b03887a
FG
115#[derive(Diagnostic)]
116#[diag(session_cannot_enable_crt_static_linux)]
f2b60f7d
FG
117pub struct CannotEnableCrtStaticLinux;
118
2b03887a 119#[derive(Diagnostic)]
49aad941
FG
120#[diag(session_sanitizer_cfi_requires_lto)]
121pub struct SanitizerCfiRequiresLto;
122
add651ee
FG
123#[derive(Diagnostic)]
124#[diag(session_sanitizer_cfi_requires_single_codegen_unit)]
125pub struct SanitizerCfiRequiresSingleCodegenUnit;
126
49aad941
FG
127#[derive(Diagnostic)]
128#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)]
129pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi;
130
131#[derive(Diagnostic)]
132#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)]
133pub struct SanitizerCfiGeneralizePointersRequiresCfi;
134
135#[derive(Diagnostic)]
136#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)]
137pub struct SanitizerCfiNormalizeIntegersRequiresCfi;
138
139#[derive(Diagnostic)]
140#[diag(session_split_lto_unit_requires_lto)]
141pub struct SplitLtoUnitRequiresLto;
f2b60f7d 142
2b03887a
FG
143#[derive(Diagnostic)]
144#[diag(session_unstable_virtual_function_elimination)]
f2b60f7d
FG
145pub struct UnstableVirtualFunctionElimination;
146
2b03887a
FG
147#[derive(Diagnostic)]
148#[diag(session_unsupported_dwarf_version)]
f2b60f7d
FG
149pub struct UnsupportedDwarfVersion {
150 pub dwarf_version: u32,
151}
152
2b03887a
FG
153#[derive(Diagnostic)]
154#[diag(session_target_stack_protector_not_supported)]
f2b60f7d
FG
155pub struct StackProtectorNotSupportedForTarget<'a> {
156 pub stack_protector: StackProtector,
157 pub target_triple: &'a TargetTriple,
158}
159
9c376795
FG
160#[derive(Diagnostic)]
161#[diag(session_branch_protection_requires_aarch64)]
162pub(crate) struct BranchProtectionRequiresAArch64;
163
2b03887a
FG
164#[derive(Diagnostic)]
165#[diag(session_split_debuginfo_unstable_platform)]
f2b60f7d
FG
166pub struct SplitDebugInfoUnstablePlatform {
167 pub debuginfo: SplitDebuginfo,
168}
169
2b03887a
FG
170#[derive(Diagnostic)]
171#[diag(session_file_is_not_writeable)]
f2b60f7d
FG
172pub struct FileIsNotWriteable<'a> {
173 pub file: &'a std::path::Path,
174}
175
add651ee
FG
176#[derive(Diagnostic)]
177#[diag(session_file_write_fail)]
178pub(crate) struct FileWriteFail<'a> {
179 pub path: &'a std::path::Path,
180 pub err: String,
181}
182
2b03887a
FG
183#[derive(Diagnostic)]
184#[diag(session_crate_name_does_not_match)]
487cf647 185pub struct CrateNameDoesNotMatch {
f2b60f7d
FG
186 #[primary_span]
187 pub span: Span,
487cf647 188 pub s: Symbol,
f2b60f7d
FG
189 pub name: Symbol,
190}
191
2b03887a
FG
192#[derive(Diagnostic)]
193#[diag(session_crate_name_invalid)]
f2b60f7d
FG
194pub struct CrateNameInvalid<'a> {
195 pub s: &'a str,
196}
197
2b03887a
FG
198#[derive(Diagnostic)]
199#[diag(session_crate_name_empty)]
f2b60f7d
FG
200pub struct CrateNameEmpty {
201 #[primary_span]
202 pub span: Option<Span>,
203}
204
2b03887a
FG
205#[derive(Diagnostic)]
206#[diag(session_invalid_character_in_create_name)]
487cf647 207pub struct InvalidCharacterInCrateName {
2b03887a 208 #[primary_span]
f2b60f7d
FG
209 pub span: Option<Span>,
210 pub character: char,
487cf647 211 pub crate_name: Symbol,
add651ee
FG
212 #[subdiagnostic]
213 pub crate_name_help: Option<InvalidCrateNameHelp>,
214}
215
216#[derive(Subdiagnostic)]
217pub enum InvalidCrateNameHelp {
218 #[help(session_invalid_character_in_create_name_help)]
219 AddCrateName,
f2b60f7d
FG
220}
221
2b03887a
FG
222#[derive(Subdiagnostic)]
223#[multipart_suggestion(session_expr_parentheses_needed, applicability = "machine-applicable")]
224pub struct ExprParenthesesNeeded {
225 #[suggestion_part(code = "(")]
226 pub left: Span,
227 #[suggestion_part(code = ")")]
228 pub right: Span,
229}
230
231impl ExprParenthesesNeeded {
232 pub fn surrounding(s: Span) -> Self {
233 ExprParenthesesNeeded { left: s.shrink_to_lo(), right: s.shrink_to_hi() }
f2b60f7d
FG
234 }
235}
2b03887a
FG
236
237#[derive(Diagnostic)]
238#[diag(session_skipping_const_checks)]
239pub struct SkippingConstChecks {
9c376795 240 #[subdiagnostic]
2b03887a
FG
241 pub unleashed_features: Vec<UnleashedFeatureHelp>,
242}
243
244#[derive(Subdiagnostic)]
245pub enum UnleashedFeatureHelp {
246 #[help(session_unleashed_feature_help_named)]
247 Named {
248 #[primary_span]
249 span: Span,
250 gate: Symbol,
251 },
252 #[help(session_unleashed_feature_help_unnamed)]
253 Unnamed {
254 #[primary_span]
255 span: Span,
256 },
257}
487cf647
FG
258
259#[derive(Diagnostic)]
260#[diag(session_invalid_literal_suffix)]
261pub(crate) struct InvalidLiteralSuffix<'a> {
262 #[primary_span]
263 #[label]
264 pub span: Span,
265 // FIXME(#100717)
266 pub kind: &'a str,
267 pub suffix: Symbol,
268}
269
270#[derive(Diagnostic)]
271#[diag(session_invalid_int_literal_width)]
272#[help]
273pub(crate) struct InvalidIntLiteralWidth {
274 #[primary_span]
275 pub span: Span,
276 pub width: String,
277}
278
279#[derive(Diagnostic)]
280#[diag(session_invalid_num_literal_base_prefix)]
281#[note]
282pub(crate) struct InvalidNumLiteralBasePrefix {
283 #[primary_span]
284 #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
285 pub span: Span,
286 pub fixed: String,
287}
288
289#[derive(Diagnostic)]
290#[diag(session_invalid_num_literal_suffix)]
291#[help]
292pub(crate) struct InvalidNumLiteralSuffix {
293 #[primary_span]
294 #[label]
295 pub span: Span,
296 pub suffix: String,
297}
298
299#[derive(Diagnostic)]
300#[diag(session_invalid_float_literal_width)]
301#[help]
302pub(crate) struct InvalidFloatLiteralWidth {
303 #[primary_span]
304 pub span: Span,
305 pub width: String,
306}
307
308#[derive(Diagnostic)]
309#[diag(session_invalid_float_literal_suffix)]
310#[help]
311pub(crate) struct InvalidFloatLiteralSuffix {
312 #[primary_span]
313 #[label]
314 pub span: Span,
315 pub suffix: String,
316}
317
318#[derive(Diagnostic)]
319#[diag(session_int_literal_too_large)]
9c376795 320#[note]
487cf647
FG
321pub(crate) struct IntLiteralTooLarge {
322 #[primary_span]
323 pub span: Span,
9c376795 324 pub limit: String,
487cf647
FG
325}
326
327#[derive(Diagnostic)]
328#[diag(session_hexadecimal_float_literal_not_supported)]
329pub(crate) struct HexadecimalFloatLiteralNotSupported {
330 #[primary_span]
331 #[label(session_not_supported)]
332 pub span: Span,
333}
334
335#[derive(Diagnostic)]
336#[diag(session_octal_float_literal_not_supported)]
337pub(crate) struct OctalFloatLiteralNotSupported {
338 #[primary_span]
339 #[label(session_not_supported)]
340 pub span: Span,
341}
342
343#[derive(Diagnostic)]
344#[diag(session_binary_float_literal_not_supported)]
345pub(crate) struct BinaryFloatLiteralNotSupported {
346 #[primary_span]
347 #[label(session_not_supported)]
348 pub span: Span,
349}
350
49aad941
FG
351#[derive(Diagnostic)]
352#[diag(session_nul_in_c_str)]
353pub(crate) struct NulInCStr {
354 #[primary_span]
355 pub span: Span,
356}
357
487cf647
FG
358pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) {
359 // Checks if `s` looks like i32 or u1234 etc.
360 fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
361 s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
362 }
363
9c376795
FG
364 // Try to lowercase the prefix if the prefix and suffix are valid.
365 fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> {
366 let mut chars = suffix.chars();
367
368 let base_char = chars.next().unwrap();
369 let base = match base_char {
370 'B' => 2,
371 'O' => 8,
372 'X' => 16,
373 _ => return None,
374 };
375
376 // check that the suffix contains only base-appropriate characters
377 let valid = prefix == "0"
378 && chars
379 .filter(|c| *c != '_')
380 .take_while(|c| *c != 'i' && *c != 'u')
381 .all(|c| c.to_digit(base).is_some());
382
9ffffee4 383 valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
487cf647
FG
384 }
385
9c376795 386 let token::Lit { kind, symbol, suffix, .. } = lit;
487cf647
FG
387 match err {
388 // `LexerError` is an error, but it was already reported
389 // by lexer, so here we don't report it the second time.
390 LitError::LexerError => {}
391 LitError::InvalidSuffix => {
392 if let Some(suffix) = suffix {
393 sess.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix });
394 }
395 }
396 LitError::InvalidIntSuffix => {
397 let suf = suffix.expect("suffix error with no suffix");
398 let suf = suf.as_str();
399 if looks_like_width_suffix(&['i', 'u'], suf) {
400 // If it looks like a width, try to be helpful.
401 sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
9c376795 402 } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
487cf647
FG
403 sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
404 } else {
405 sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
406 }
407 }
408 LitError::InvalidFloatSuffix => {
409 let suf = suffix.expect("suffix error with no suffix");
410 let suf = suf.as_str();
411 if looks_like_width_suffix(&['f'], suf) {
412 // If it looks like a width, try to be helpful.
413 sess.emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() });
414 } else {
415 sess.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() });
416 }
417 }
418 LitError::NonDecimalFloat(base) => {
419 match base {
420 16 => sess.emit_err(HexadecimalFloatLiteralNotSupported { span }),
421 8 => sess.emit_err(OctalFloatLiteralNotSupported { span }),
422 2 => sess.emit_err(BinaryFloatLiteralNotSupported { span }),
423 _ => unreachable!(),
424 };
425 }
9c376795
FG
426 LitError::IntTooLarge(base) => {
427 let max = u128::MAX;
428 let limit = match base {
429 2 => format!("{max:#b}"),
430 8 => format!("{max:#o}"),
431 16 => format!("{max:#x}"),
432 _ => format!("{max}"),
433 };
434 sess.emit_err(IntLiteralTooLarge { span, limit });
487cf647 435 }
49aad941
FG
436 LitError::NulInCStr(range) => {
437 let lo = BytePos(span.lo().0 + range.start as u32 + 2);
438 let hi = BytePos(span.lo().0 + range.end as u32 + 2);
439 let span = span.with_lo(lo).with_hi(hi);
440 sess.emit_err(NulInCStr { span });
441 }
487cf647
FG
442 }
443}
9ffffee4
FG
444
445#[derive(Diagnostic)]
446#[diag(session_optimization_fuel_exhausted)]
447pub struct OptimisationFuelExhausted {
448 pub msg: String,
449}
fe692bf9
FG
450
451#[derive(Diagnostic)]
452#[diag(session_incompatible_linker_flavor)]
453#[note]
454pub struct IncompatibleLinkerFlavor {
455 pub flavor: &'static str,
456 pub compatible_list: String,
457}