Skip to content
Closed
46 changes: 25 additions & 21 deletions compiler/rustc_session/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for FeatureGateError {
}
}

#[derive(Subdiagnostic)]
pub struct FeatureGateSubdiagnostic {
#[subdiagnostic]
pub(crate) issue: Option<FeatureDiagnosticForIssue>,
#[subdiagnostic]
pub(crate) enable_feature: Option<EnableFeatureSubdiagnostic>,
#[subdiagnostic]
pub(crate) upgrade_compiler: Option<SuggestUpgradeCompiler>,
}

#[derive(Subdiagnostic)]
#[note(session_feature_diagnostic_for_issue)]
pub(crate) struct FeatureDiagnosticForIssue {
Expand All @@ -51,27 +61,21 @@ impl SuggestUpgradeCompiler {
}

#[derive(Subdiagnostic)]
#[help(session_feature_diagnostic_help)]
pub(crate) struct FeatureDiagnosticHelp {
pub(crate) feature: Symbol,
}

#[derive(Subdiagnostic)]
#[suggestion(
session_feature_diagnostic_suggestion,
applicability = "maybe-incorrect",
code = "#![feature({feature})]\n"
)]
pub struct FeatureDiagnosticSuggestion {
pub feature: Symbol,
#[primary_span]
pub span: Span,
}

#[derive(Subdiagnostic)]
#[help(session_cli_feature_diagnostic_help)]
pub(crate) struct CliFeatureDiagnosticHelp {
pub(crate) feature: Symbol,
pub(crate) enum EnableFeatureSubdiagnostic {
#[help(session_feature_diagnostic_help)]
AddAttrHelp { feature: Symbol },
#[suggestion(
session_feature_diagnostic_suggestion,
applicability = "maybe-incorrect",
code = "#![feature({feature})]\n"
)]
AddAttrSuggestion {
feature: Symbol,
#[primary_span]
span: Span,
},
#[help(session_cli_feature_diagnostic_help)]
AddCliHelp { feature: Symbol },
}

#[derive(Diagnostic)]
Expand Down
38 changes: 22 additions & 16 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use rustc_span::{Span, Symbol};

use crate::config::{Cfg, CheckCfg};
use crate::errors::{
CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp,
FeatureDiagnosticSuggestion, FeatureGateError, SuggestUpgradeCompiler,
EnableFeatureSubdiagnostic, FeatureDiagnosticForIssue, FeatureGateError,
FeatureGateSubdiagnostic, SuggestUpgradeCompiler,
};
use crate::lint::builtin::UNSTABLE_SYNTAX_PRE_EXPANSION;
use crate::lint::{BufferedEarlyLint, BuiltinLintDiag, Lint, LintId};
Expand Down Expand Up @@ -177,26 +177,32 @@ pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
feature_from_cli: bool,
inject_span: Option<Span>,
) {
if let Some(n) = find_feature_issue(feature, issue) {
err.subdiagnostic(FeatureDiagnosticForIssue { n });
}
let issue = find_feature_issue(feature, issue).map(|n| FeatureDiagnosticForIssue { n });

// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.psess.unstable_features.is_nightly_build() {
if feature_from_cli {
err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
let (enable_feature, upgrade_compiler) = if sess.psess.unstable_features.is_nightly_build() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you split this in two? That will be more readable. Maybe cache is_nightly_build() as it looks at env vars.

let enable_feature = if feature_from_cli {
EnableFeatureSubdiagnostic::AddCliHelp { feature }
} else if let Some(span) = inject_span {
err.subdiagnostic(FeatureDiagnosticSuggestion { feature, span });
EnableFeatureSubdiagnostic::AddAttrSuggestion { feature, span }
} else {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
EnableFeatureSubdiagnostic::AddAttrHelp { feature }
};

if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
let upgrade_compiler = if sess.opts.unstable_opts.ui_testing {
Some(SuggestUpgradeCompiler::ui_testing())
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
Some(suggestion)
} else {
None
};

(Some(enable_feature), upgrade_compiler)
} else {
(None, None)
};

err.subdiagnostic(FeatureGateSubdiagnostic { issue, upgrade_compiler, enable_feature });
}

/// Info about a parsing session.
Expand Down