Skip to content

Commit a65be18

Browse files
committed
rustc_session: turn feature gate subdiagnostic into struct
1 parent dfce191 commit a65be18

File tree

2 files changed

+63
-39
lines changed

2 files changed

+63
-39
lines changed

compiler/rustc_session/src/errors.rs

+40-22
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::token;
44
use rustc_ast::util::literal::LitError;
55
use rustc_errors::{
66
codes::*, Diag, DiagCtxt, DiagMessage, Diagnostic, EmissionGuarantee, ErrorGuaranteed, Level,
7-
MultiSpan,
7+
MultiSpan, Subdiagnostic,
88
};
99
use rustc_macros::Diagnostic;
1010
use rustc_span::{Span, Symbol};
@@ -24,6 +24,30 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for FeatureGateError {
2424
}
2525
}
2626

27+
pub struct FeatureGateSubdiagnostic {
28+
pub(crate) issue: Option<FeatureDiagnosticForIssue>,
29+
pub(crate) enable_feature: Option<EnableFeatureSubdiagnostic>,
30+
pub(crate) upgrade_compiler: Option<SuggestUpgradeCompiler>,
31+
}
32+
33+
impl Subdiagnostic for FeatureGateSubdiagnostic {
34+
fn add_to_diag_with<G: EmissionGuarantee, F: rustc_errors::SubdiagMessageOp<G>>(
35+
self,
36+
diag: &mut Diag<'_, G>,
37+
f: F,
38+
) {
39+
if let Some(issue) = self.issue {
40+
issue.add_to_diag_with(diag, |diag, msg| f(diag, msg));
41+
}
42+
if let Some(enable_feature) = self.enable_feature {
43+
enable_feature.add_to_diag_with(diag, |diag, msg| f(diag, msg));
44+
}
45+
if let Some(upgrade_compiler) = self.upgrade_compiler {
46+
upgrade_compiler.add_to_diag_with(diag, |diag, msg| f(diag, msg));
47+
}
48+
}
49+
}
50+
2751
#[derive(Subdiagnostic)]
2852
#[note(session_feature_diagnostic_for_issue)]
2953
pub(crate) struct FeatureDiagnosticForIssue {
@@ -49,27 +73,21 @@ impl SuggestUpgradeCompiler {
4973
}
5074

5175
#[derive(Subdiagnostic)]
52-
#[help(session_feature_diagnostic_help)]
53-
pub(crate) struct FeatureDiagnosticHelp {
54-
pub(crate) feature: Symbol,
55-
}
56-
57-
#[derive(Subdiagnostic)]
58-
#[suggestion(
59-
session_feature_diagnostic_suggestion,
60-
applicability = "maybe-incorrect",
61-
code = "#![feature({feature})]\n"
62-
)]
63-
pub struct FeatureDiagnosticSuggestion {
64-
pub feature: Symbol,
65-
#[primary_span]
66-
pub span: Span,
67-
}
68-
69-
#[derive(Subdiagnostic)]
70-
#[help(session_cli_feature_diagnostic_help)]
71-
pub(crate) struct CliFeatureDiagnosticHelp {
72-
pub(crate) feature: Symbol,
76+
pub(crate) enum EnableFeatureSubdiagnostic {
77+
#[help(session_feature_diagnostic_help)]
78+
AddAttrHelp { feature: Symbol },
79+
#[suggestion(
80+
session_feature_diagnostic_suggestion,
81+
applicability = "maybe-incorrect",
82+
code = "#![feature({feature})]\n"
83+
)]
84+
AddAttrSuggestion {
85+
feature: Symbol,
86+
#[primary_span]
87+
span: Span,
88+
},
89+
#[help(session_cli_feature_diagnostic_help)]
90+
AddCliHelp { feature: Symbol },
7391
}
7492

7593
#[derive(Diagnostic)]

compiler/rustc_session/src/parse.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
44
use crate::config::{Cfg, CheckCfg};
55
use crate::errors::{
6-
CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp,
7-
FeatureDiagnosticSuggestion, FeatureGateError, SuggestUpgradeCompiler,
6+
EnableFeatureSubdiagnostic, FeatureDiagnosticForIssue, FeatureGateError,
7+
FeatureGateSubdiagnostic, SuggestUpgradeCompiler,
88
};
99
use crate::lint::{
1010
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiag, Lint, LintId,
@@ -177,26 +177,32 @@ pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
177177
feature_from_cli: bool,
178178
inject_span: Option<Span>,
179179
) {
180-
if let Some(n) = find_feature_issue(feature, issue) {
181-
err.subdiagnostic(sess.dcx(), FeatureDiagnosticForIssue { n });
182-
}
180+
let issue = find_feature_issue(feature, issue).map(|n| FeatureDiagnosticForIssue { n });
183181

184182
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
185-
if sess.psess.unstable_features.is_nightly_build() {
186-
if feature_from_cli {
187-
err.subdiagnostic(sess.dcx(), CliFeatureDiagnosticHelp { feature });
183+
let (enable_feature, upgrade_compiler) = if sess.psess.unstable_features.is_nightly_build() {
184+
let enable_feature = if feature_from_cli {
185+
EnableFeatureSubdiagnostic::AddCliHelp { feature }
188186
} else if let Some(span) = inject_span {
189-
err.subdiagnostic(sess.dcx(), FeatureDiagnosticSuggestion { feature, span });
187+
EnableFeatureSubdiagnostic::AddAttrSuggestion { feature, span }
190188
} else {
191-
err.subdiagnostic(sess.dcx(), FeatureDiagnosticHelp { feature });
192-
}
189+
EnableFeatureSubdiagnostic::AddAttrHelp { feature }
190+
};
193191

194-
if sess.opts.unstable_opts.ui_testing {
195-
err.subdiagnostic(sess.dcx(), SuggestUpgradeCompiler::ui_testing());
196-
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
197-
err.subdiagnostic(sess.dcx(), suggestion);
198-
}
199-
}
192+
let upgrade_compiler = if sess.opts.unstable_opts.ui_testing {
193+
Some(SuggestUpgradeCompiler::ui_testing())
194+
} else {
195+
SuggestUpgradeCompiler::new()
196+
};
197+
198+
(Some(enable_feature), upgrade_compiler)
199+
} else {
200+
(None, None)
201+
};
202+
203+
let subdiagnostic = FeatureGateSubdiagnostic { issue, upgrade_compiler, enable_feature };
204+
205+
err.subdiagnostic(sess.dcx(), subdiagnostic);
200206
}
201207

202208
/// Info about a parsing session.

0 commit comments

Comments
 (0)