]>
Commit | Line | Data |
---|---|---|
f2b60f7d FG |
1 | use std::num::NonZeroU32; |
2 | ||
3 | use crate::cgu_reuse_tracker::CguReuse; | |
487cf647 FG |
4 | use crate::parse::ParseSess; |
5 | use rustc_ast::token; | |
6 | use rustc_ast::util::literal::LitError; | |
9ffffee4 | 7 | use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan}; |
2b03887a | 8 | use rustc_macros::Diagnostic; |
49aad941 | 9 | use rustc_span::{BytePos, Span, Symbol}; |
f2b60f7d FG |
10 | use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; |
11 | ||
2b03887a FG |
12 | #[derive(Diagnostic)] |
13 | #[diag(session_incorrect_cgu_reuse_type)] | |
f2b60f7d FG |
14 | pub 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 |
25 | pub struct CguNotRecorded<'a> { |
26 | pub cgu_user_name: &'a str, | |
27 | pub cgu_name: &'a str, | |
28 | } | |
29 | ||
9ffffee4 | 30 | pub struct FeatureGateError { |
f2b60f7d | 31 | pub span: MultiSpan, |
9ffffee4 FG |
32 | pub explain: DiagnosticMessage, |
33 | } | |
34 | ||
35 | impl<'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 |
50 | pub struct FeatureDiagnosticForIssue { |
51 | pub n: NonZeroU32, | |
52 | } | |
53 | ||
2b03887a FG |
54 | #[derive(Subdiagnostic)] |
55 | #[help(session_feature_diagnostic_help)] | |
f2b60f7d FG |
56 | pub struct FeatureDiagnosticHelp { |
57 | pub feature: Symbol, | |
58 | } | |
59 | ||
781aab86 FG |
60 | #[derive(Subdiagnostic)] |
61 | #[help(session_cli_feature_diagnostic_help)] | |
62 | pub struct CliFeatureDiagnosticHelp { | |
63 | pub feature: Symbol, | |
64 | } | |
65 | ||
2b03887a FG |
66 | #[derive(Diagnostic)] |
67 | #[diag(session_not_circumvent_feature)] | |
f2b60f7d FG |
68 | pub struct NotCircumventFeature; |
69 | ||
2b03887a FG |
70 | #[derive(Diagnostic)] |
71 | #[diag(session_linker_plugin_lto_windows_not_supported)] | |
f2b60f7d FG |
72 | pub struct LinkerPluginToWindowsNotSupported; |
73 | ||
2b03887a FG |
74 | #[derive(Diagnostic)] |
75 | #[diag(session_profile_use_file_does_not_exist)] | |
f2b60f7d FG |
76 | pub 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 |
82 | pub 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 |
88 | pub struct TargetRequiresUnwindTables; |
89 | ||
9ffffee4 FG |
90 | #[derive(Diagnostic)] |
91 | #[diag(session_instrumentation_not_supported)] | |
92 | pub struct InstrumentationNotSupported { | |
93 | pub us: String, | |
94 | } | |
95 | ||
2b03887a FG |
96 | #[derive(Diagnostic)] |
97 | #[diag(session_sanitizer_not_supported)] | |
f2b60f7d FG |
98 | pub struct SanitizerNotSupported { |
99 | pub us: String, | |
100 | } | |
101 | ||
2b03887a FG |
102 | #[derive(Diagnostic)] |
103 | #[diag(session_sanitizers_not_supported)] | |
f2b60f7d FG |
104 | pub struct SanitizersNotSupported { |
105 | pub us: String, | |
106 | } | |
107 | ||
2b03887a FG |
108 | #[derive(Diagnostic)] |
109 | #[diag(session_cannot_mix_and_match_sanitizers)] | |
f2b60f7d FG |
110 | pub 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 |
117 | pub struct CannotEnableCrtStaticLinux; |
118 | ||
2b03887a | 119 | #[derive(Diagnostic)] |
49aad941 FG |
120 | #[diag(session_sanitizer_cfi_requires_lto)] |
121 | pub struct SanitizerCfiRequiresLto; | |
122 | ||
add651ee FG |
123 | #[derive(Diagnostic)] |
124 | #[diag(session_sanitizer_cfi_requires_single_codegen_unit)] | |
125 | pub struct SanitizerCfiRequiresSingleCodegenUnit; | |
126 | ||
49aad941 FG |
127 | #[derive(Diagnostic)] |
128 | #[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] | |
129 | pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi; | |
130 | ||
131 | #[derive(Diagnostic)] | |
132 | #[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] | |
133 | pub struct SanitizerCfiGeneralizePointersRequiresCfi; | |
134 | ||
135 | #[derive(Diagnostic)] | |
136 | #[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] | |
137 | pub struct SanitizerCfiNormalizeIntegersRequiresCfi; | |
138 | ||
139 | #[derive(Diagnostic)] | |
140 | #[diag(session_split_lto_unit_requires_lto)] | |
141 | pub struct SplitLtoUnitRequiresLto; | |
f2b60f7d | 142 | |
2b03887a FG |
143 | #[derive(Diagnostic)] |
144 | #[diag(session_unstable_virtual_function_elimination)] | |
f2b60f7d FG |
145 | pub struct UnstableVirtualFunctionElimination; |
146 | ||
2b03887a FG |
147 | #[derive(Diagnostic)] |
148 | #[diag(session_unsupported_dwarf_version)] | |
f2b60f7d FG |
149 | pub struct UnsupportedDwarfVersion { |
150 | pub dwarf_version: u32, | |
151 | } | |
152 | ||
2b03887a FG |
153 | #[derive(Diagnostic)] |
154 | #[diag(session_target_stack_protector_not_supported)] | |
f2b60f7d FG |
155 | pub 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)] | |
162 | pub(crate) struct BranchProtectionRequiresAArch64; | |
163 | ||
2b03887a FG |
164 | #[derive(Diagnostic)] |
165 | #[diag(session_split_debuginfo_unstable_platform)] | |
f2b60f7d FG |
166 | pub struct SplitDebugInfoUnstablePlatform { |
167 | pub debuginfo: SplitDebuginfo, | |
168 | } | |
169 | ||
2b03887a FG |
170 | #[derive(Diagnostic)] |
171 | #[diag(session_file_is_not_writeable)] | |
f2b60f7d FG |
172 | pub struct FileIsNotWriteable<'a> { |
173 | pub file: &'a std::path::Path, | |
174 | } | |
175 | ||
add651ee FG |
176 | #[derive(Diagnostic)] |
177 | #[diag(session_file_write_fail)] | |
178 | pub(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 | 185 | pub 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 |
194 | pub struct CrateNameInvalid<'a> { |
195 | pub s: &'a str, | |
196 | } | |
197 | ||
2b03887a FG |
198 | #[derive(Diagnostic)] |
199 | #[diag(session_crate_name_empty)] | |
f2b60f7d FG |
200 | pub 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 | 207 | pub 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)] | |
217 | pub 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")] | |
224 | pub struct ExprParenthesesNeeded { | |
225 | #[suggestion_part(code = "(")] | |
226 | pub left: Span, | |
227 | #[suggestion_part(code = ")")] | |
228 | pub right: Span, | |
229 | } | |
230 | ||
231 | impl 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)] | |
239 | pub struct SkippingConstChecks { | |
9c376795 | 240 | #[subdiagnostic] |
2b03887a FG |
241 | pub unleashed_features: Vec<UnleashedFeatureHelp>, |
242 | } | |
243 | ||
244 | #[derive(Subdiagnostic)] | |
245 | pub 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)] | |
261 | pub(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] | |
273 | pub(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] | |
282 | pub(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] | |
292 | pub(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] | |
302 | pub(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] | |
311 | pub(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 |
321 | pub(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)] | |
329 | pub(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)] | |
337 | pub(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)] | |
345 | pub(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)] | |
353 | pub(crate) struct NulInCStr { | |
354 | #[primary_span] | |
355 | pub span: Span, | |
356 | } | |
357 | ||
487cf647 FG |
358 | pub 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)] | |
447 | pub struct OptimisationFuelExhausted { | |
448 | pub msg: String, | |
449 | } | |
fe692bf9 FG |
450 | |
451 | #[derive(Diagnostic)] | |
452 | #[diag(session_incompatible_linker_flavor)] | |
453 | #[note] | |
454 | pub struct IncompatibleLinkerFlavor { | |
455 | pub flavor: &'static str, | |
456 | pub compatible_list: String, | |
457 | } |