Reenable early feature-gates as future-compat warnings

This commit is contained in:
Christopher Durham 2022-08-17 06:52:47 -05:00
parent e9e46c95ce
commit 767239f740
11 changed files with 224 additions and 34 deletions

View file

@ -2,15 +2,17 @@
//! It also serves as an input to the parser itself.
use crate::config::CheckCfg;
use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
use crate::lint::{
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
};
use crate::SessionDiagnostic;
use rustc_ast::node_id::NodeId;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
use rustc_errors::{
error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder,
DiagnosticMessage, ErrorGuaranteed, MultiSpan,
error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
DiagnosticMessage, ErrorGuaranteed, MultiSpan, StashKey,
};
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
use rustc_span::edition::Edition;
@ -101,11 +103,58 @@ pub fn feature_err_issue<'a>(
issue: GateIssue,
explain: &str,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span() {
sess.span_diagnostic
.steal_diagnostic(span, StashKey::EarlySyntaxWarning)
.map(|err| err.cancel());
}
let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658));
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
err
}
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) {
feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
}
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
///
/// This variant allows you to control whether it is a library or language feature.
/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`.
pub fn feature_warn_issue<'a>(
sess: &'a ParseSess,
feature: Symbol,
span: Span,
issue: GateIssue,
explain: &str,
) {
let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
// Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
let future_incompatible = lint.future_incompatible.as_ref().unwrap();
err.code(DiagnosticId::Lint {
name: lint.name_lower(),
has_future_breakage: false,
is_force_warn: false,
});
err.warn(lint.desc);
err.note(format!("for more information, see {}", future_incompatible.reference));
// A later feature_err call can steal and cancel this warning.
err.stash(span, StashKey::EarlySyntaxWarning);
}
/// Adds the diagnostics for a feature to an existing error.
pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);