diff options
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 96 |
4 files changed, 72 insertions, 38 deletions
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 1f270fcf56b..0fcd61d1e58 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -87,7 +87,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType { Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error { .. } => { AnnotationType::Error } - Level::Warning => AnnotationType::Warning, + Level::Warning(_) => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help => AnnotationType::Help, // FIXME(#59346): Not sure how to map this level diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index eaceecc1667..e559053bdfb 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -208,7 +208,7 @@ impl Diagnostic { | Level::Error { .. } | Level::FailureNote => true, - Level::Warning + Level::Warning(_) | Level::Note | Level::OnceNote | Level::Help @@ -221,7 +221,9 @@ impl Diagnostic { &mut self, unstable_to_stable: &FxHashMap<LintExpectationId, LintExpectationId>, ) { - if let Level::Expect(expectation_id) = &mut self.level { + if let Level::Expect(expectation_id) | Level::Warning(Some(expectation_id)) = + &mut self.level + { if expectation_id.is_stable() { return; } @@ -445,7 +447,7 @@ impl Diagnostic { /// Add a warning attached to this diagnostic. pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { - self.sub(Level::Warning, msg, MultiSpan::new(), None); + self.sub(Level::Warning(None), msg, MultiSpan::new(), None); self } @@ -456,7 +458,7 @@ impl Diagnostic { sp: S, msg: impl Into<SubdiagnosticMessage>, ) -> &mut Self { - self.sub(Level::Warning, msg, sp.into(), None); + self.sub(Level::Warning(None), msg, sp.into(), None); self } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index fff35ac6ac8..d4d1491c169 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -154,7 +154,7 @@ impl Emitter for JsonEmitter { .into_iter() .map(|mut diag| { if diag.level == crate::Level::Allow { - diag.level = crate::Level::Warning; + diag.level = crate::Level::Warning(None); } FutureBreakageItem { diagnostic: Diagnostic::from_errors_diagnostic(&diag, self) } }) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 83fe2a2df89..1f6f271899d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -658,6 +658,23 @@ impl Handler { result } + /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. + /// The `id` is used for lint emissions which should also fulfill a lint expectation. + /// + /// Attempting to `.emit()` the builder will only emit if either: + /// * `can_emit_warnings` is `true` + /// * `is_force_warn` was set in `DiagnosticId::Lint` + pub fn struct_span_warn_with_expectation( + &self, + span: impl Into<MultiSpan>, + msg: impl Into<DiagnosticMessage>, + id: LintExpectationId, + ) -> DiagnosticBuilder<'_, ()> { + let mut result = self.struct_warn_with_expectation(msg, id); + result.set_span(span); + result + } + /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. pub fn struct_span_allow( &self, @@ -688,7 +705,21 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Level::Warning, msg) + DiagnosticBuilder::new(self, Level::Warning(None), msg) + } + + /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for + /// lint emissions which should also fulfill a lint expectation. + /// + /// Attempting to `.emit()` the builder will only emit if either: + /// * `can_emit_warnings` is `true` + /// * `is_force_warn` was set in `DiagnosticId::Lint` + pub fn struct_warn_with_expectation( + &self, + msg: impl Into<DiagnosticMessage>, + id: LintExpectationId, + ) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Level::Warning(Some(id)), msg) } /// Construct a builder at the `Allow` level with the `msg`. @@ -842,7 +873,7 @@ impl Handler { } pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { - self.emit_diag_at_span(Diagnostic::new(Warning, msg), span); + self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); } pub fn span_warn_with_code( @@ -851,7 +882,7 @@ impl Handler { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) { - self.emit_diag_at_span(Diagnostic::new_with_code(Warning, Some(code), msg), span); + self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! { @@ -905,7 +936,7 @@ impl Handler { } pub fn warn(&self, msg: impl Into<DiagnosticMessage>) { - let mut db = DiagnosticBuilder::new(self, Warning, msg); + let mut db = DiagnosticBuilder::new(self, Warning(None), msg); db.emit(); } @@ -1010,13 +1041,10 @@ impl Handler { for mut diag in diags.into_iter() { diag.update_unstable_expectation_id(unstable_to_stable); - let stable_id = diag - .level - .get_expectation_id() - .expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`"); - inner.fulfilled_expectations.insert(stable_id); - - (*TRACK_DIAGNOSTICS)(&diag); + // Here the diagnostic is given back to `emit_diagnostic` where it was first + // intercepted. Now it should be processed as usual, since the unstable expectation + // id is now stable. + inner.emit_diagnostic(&mut diag); } } @@ -1066,6 +1094,15 @@ impl HandlerInner { // FIXME(eddyb) this should ideally take `diagnostic` by value. fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> { + // The `LintExpectationId` can be stable or unstable depending on when it was created. + // Diagnostics created before the definition of `HirId`s are unstable and can not yet + // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by + // a stable one by the `LintLevelsBuilder`. + if let Some(LintExpectationId::Unstable { .. }) = diagnostic.level.get_expectation_id() { + self.unstable_expect_diagnostics.push(diagnostic.clone()); + return None; + } + if diagnostic.level == Level::DelayedBug { // FIXME(eddyb) this should check for `has_errors` and stop pushing // once *any* errors were emitted (and truncate `delayed_span_bugs` @@ -1082,7 +1119,12 @@ impl HandlerInner { self.future_breakage_diagnostics.push(diagnostic.clone()); } - if diagnostic.level == Warning + if let Some(expectation_id) = diagnostic.level.get_expectation_id() { + self.suppressed_expected_diag = true; + self.fulfilled_expectations.insert(expectation_id); + } + + if matches!(diagnostic.level, Warning(_)) && !self.flags.can_emit_warnings && !diagnostic.is_force_warn() { @@ -1092,22 +1134,9 @@ impl HandlerInner { return None; } - // The `LintExpectationId` can be stable or unstable depending on when it was created. - // Diagnostics created before the definition of `HirId`s are unstable and can not yet - // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by - // a stable one by the `LintLevelsBuilder`. - if let Level::Expect(LintExpectationId::Unstable { .. }) = diagnostic.level { - self.unstable_expect_diagnostics.push(diagnostic.clone()); - return None; - } - (*TRACK_DIAGNOSTICS)(diagnostic); - if let Level::Expect(expectation_id) = diagnostic.level { - self.suppressed_expected_diag = true; - self.fulfilled_expectations.insert(expectation_id); - return None; - } else if diagnostic.level == Allow { + if matches!(diagnostic.level, Level::Expect(_) | Level::Allow) { return None; } @@ -1144,7 +1173,7 @@ impl HandlerInner { self.emitter.emit_diagnostic(&diagnostic); if diagnostic.is_error() { self.deduplicated_err_count += 1; - } else if diagnostic.level == Warning { + } else if let Warning(_) = diagnostic.level { self.deduplicated_warn_count += 1; } } @@ -1197,7 +1226,7 @@ impl HandlerInner { match (errors.len(), warnings.len()) { (0, 0) => return, (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new( - Level::Warning, + Level::Warning(None), DiagnosticMessage::Str(warnings), )), (_, 0) => { @@ -1430,7 +1459,10 @@ pub enum Level { /// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called. lint: bool, }, - Warning, + /// This [`LintExpectationId`] is used for expected lint diagnostics, which should + /// also emit a warning due to the `force-warn` flag. In all other cases this should + /// be `None`. + Warning(Option<LintExpectationId>), Note, /// A note that is only emitted once. OnceNote, @@ -1453,7 +1485,7 @@ impl Level { Bug | DelayedBug | Fatal | Error { .. } => { spec.set_fg(Some(Color::Red)).set_intense(true); } - Warning => { + Warning(_) => { spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); } Note | OnceNote => { @@ -1472,7 +1504,7 @@ impl Level { match self { Bug | DelayedBug => "error: internal compiler error", Fatal | Error { .. } => "error", - Warning => "warning", + Warning(_) => "warning", Note | OnceNote => "note", Help => "help", FailureNote => "failure-note", @@ -1487,7 +1519,7 @@ impl Level { pub fn get_expectation_id(&self) -> Option<LintExpectationId> { match self { - Level::Expect(id) => Some(*id), + Level::Expect(id) | Level::Warning(Some(id)) => Some(*id), _ => None, } } |
