Rollup merge of #155980 - nnethercote:mv-feature-methods, r=TaKO8Ki

Move `feature*` methods from `parse` mod to `errors` mod.

As the FIXME comment says, these no longer use `ParseSess` and so the `parse` mod is not a good place for them. The `errors` mod is a better home.

r? @TaKO8Ki
This commit is contained in:
Jacob Pratt
2026-04-30 22:28:33 -04:00
committed by GitHub
43 changed files with 216 additions and 220 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::msg;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{Span, sym};
use rustc_target::asm;
+1 -1
View File
@@ -1693,7 +1693,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&& !self.tcx.features().coroutines()
&& !self.tcx.features().gen_blocks()
{
rustc_session::parse::feature_err(
rustc_session::errors::feature_err(
&self.tcx.sess,
sym::yield_expr,
span,
+1 -1
View File
@@ -62,7 +62,7 @@ use rustc_macros::extension;
use rustc_middle::hir::{self as mid_hir};
use rustc_middle::span_bug;
use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt};
use rustc_session::parse::add_feature_diagnostics;
use rustc_session::errors::add_feature_diagnostics;
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
use smallvec::SmallVec;
+1 -1
View File
@@ -6,7 +6,7 @@ use rustc_hir::def::{DefKind, PartialRes, PerNS, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, GenericArg};
use rustc_middle::{span_bug, ty};
use rustc_session::parse::add_feature_diagnostics;
use rustc_session::errors::add_feature_diagnostics;
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
use smallvec::smallvec;
use tracing::{debug, instrument};
+1 -1
View File
@@ -3,7 +3,7 @@ use std::fmt;
use rustc_abi::ExternAbi;
use rustc_feature::Features;
use rustc_session::Session;
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
@@ -30,11 +30,11 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagCtxtHandle, Diagnostic, LintBuffer};
use rustc_feature::Features;
use rustc_session::Session;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::{
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,
PATTERNS_IN_FNS_WITHOUT_BODY, UNUSED_VISIBILITIES,
};
use rustc_session::parse::feature_err;
use rustc_span::{Ident, Span, kw, sym};
use rustc_target::spec::{AbiMap, AbiMapping};
use thin_vec::thin_vec;
@@ -6,7 +6,7 @@ use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Feat
use rustc_hir::Attribute;
use rustc_hir::attrs::AttributeKind;
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_warn};
use rustc_session::errors::{feature_err, feature_warn};
use rustc_span::{Span, Spanned, Symbol, sym};
use thin_vec::ThinVec;
@@ -13,8 +13,9 @@ use rustc_parse::parser::{ForceCollect, Parser, Recovery};
use rustc_parse::{exp, parse_in};
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::parse::{ParseSess, feature_err};
use rustc_session::parse::ParseSess;
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use thin_vec::ThinVec;
@@ -1,5 +1,5 @@
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::edition::Edition::Edition2024;
use super::prelude::*;
@@ -5,7 +5,7 @@ use rustc_hir::Target;
use rustc_hir::attrs::{
AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow,
};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{Span, Symbol, edition, sym};
use thin_vec::ThinVec;
@@ -3,8 +3,8 @@ use rustc_feature::Features;
use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_hir::attrs::*;
use rustc_session::Session;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition::Edition2024;
use rustc_span::kw;
use rustc_target::spec::{Arch, BinaryFormat};
@@ -12,8 +12,8 @@ use rustc_middle::middle::codegen_fn_attrs::{
use rustc_middle::mono::Visibility;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self as ty, TyCtxt};
use rustc_session::errors::feature_err;
use rustc_session::lint;
use rustc_session::parse::feature_err;
use rustc_span::{Span, sym};
use rustc_target::spec::Os;
@@ -7,8 +7,8 @@ use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, edit_distance, sym};
use rustc_target::spec::{Arch, SanitizerSet};
use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
@@ -14,7 +14,7 @@ use rustc_middle::ty::{
self, AssocContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef,
Ty, suggest_constraining_type_param,
};
use rustc_session::parse::add_feature_diagnostics;
use rustc_session::errors::add_feature_diagnostics;
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
use rustc_trait_selection::error_reporting::traits::call_kind::{
CallDesugaringKind, CallKind, call_kind,
+1 -1
View File
@@ -27,7 +27,7 @@ use rustc_hir::{
};
use rustc_parse::parser::Recovery;
use rustc_session::Session;
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{STDLIB_STABLE_CRATES, Span, Symbol, sym};
use tracing::instrument;
+1 -1
View File
@@ -30,8 +30,8 @@ use rustc_parse::parser::{
RecoverColon, RecoverComma, Recovery, token_descr,
};
use rustc_session::Session;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
use rustc_session::parse::feature_err;
use rustc_span::hygiene::SyntaxContext;
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym};
use smallvec::SmallVec;
+2 -1
View File
@@ -23,7 +23,8 @@ use rustc_lint_defs::builtin::{
use rustc_parse::exp;
use rustc_parse::parser::{Parser, Recovery};
use rustc_session::Session;
use rustc_session::parse::{ParseSess, feature_err};
use rustc_session::errors::feature_err;
use rustc_session::parse::ParseSess;
use rustc_span::edition::Edition;
use rustc_span::hygiene::Transparency;
use rustc_span::{Ident, Span, Symbol, kw, sym};
+1 -1
View File
@@ -5,7 +5,7 @@ use rustc_ast_pretty::pprust;
use rustc_errors::Applicability;
use rustc_feature::Features;
use rustc_session::Session;
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::edition::Edition;
use rustc_span::{Ident, Span, kw, sym};
+2 -2
View File
@@ -92,7 +92,7 @@ use rustc_middle::ty::{
Unnormalized,
};
use rustc_middle::{bug, span_bug};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -312,7 +312,7 @@ fn default_body_is_unstable(
});
let inject_span = item_did.is_local().then(|| tcx.crate_level_attribute_injection_span());
rustc_session::parse::add_feature_diagnostics_for_issue(
rustc_session::errors::add_feature_diagnostics_for_issue(
&mut err,
&tcx.sess,
feature,
@@ -27,7 +27,7 @@ use rustc_middle::ty::{
Unnormalized, Upcast,
};
use rustc_middle::{bug, span_bug};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{DUMMY_SP, Span, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuildExt};
@@ -11,7 +11,7 @@ use rustc_hir::LangItem;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, elaborate};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{ErrorGuaranteed, sym};
use tracing::debug;
@@ -1272,7 +1272,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
&& !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
&& !self.tcx.features().anonymous_lifetime_in_impl_trait()
{
let mut diag: rustc_errors::Diag<'_> = rustc_session::parse::feature_err(
let mut diag: rustc_errors::Diag<'_> = rustc_session::errors::feature_err(
&self.tcx.sess,
sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.ident.span,
@@ -505,7 +505,7 @@ fn infer_placeholder_type<'tcx>(
fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
if !tcx.features().inherent_associated_types() {
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::sym;
feature_err(
&tcx.sess,
@@ -16,7 +16,7 @@ use rustc_middle::ty::{
self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
suggest_constraining_type_param,
};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
@@ -43,8 +43,8 @@ use rustc_middle::ty::{
const_lit_matches_ty, fold_regions,
};
use rustc_middle::{bug, span_bug};
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_session::parse::feature_err;
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::wf::object_region_bounds;
+1 -1
View File
@@ -89,7 +89,7 @@ use rustc_middle::mir::interpret::GlobalId;
use rustc_middle::query::Providers;
use rustc_middle::ty::{Const, Ty, TyCtxt};
use rustc_middle::{middle, ty};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;
+2 -3
View File
@@ -30,8 +30,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_session::parse::feature_err;
use rustc_session::errors::{ExprParenthesesNeeded, feature_err};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::{Ident, Span, Spanned, Symbol, kw, sym};
@@ -3767,7 +3766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block);
if !self.tcx.features().offset_of_enum() {
rustc_session::parse::feature_err(
rustc_session::errors::feature_err(
&self.tcx.sess,
sym::offset_of_enum,
ident.span,
+1 -1
View File
@@ -21,8 +21,8 @@ use rustc_infer::infer::RegionVariableOrigin;
use rustc_middle::traits::PatternOriginExpr;
use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
+1 -1
View File
@@ -39,8 +39,8 @@ use rustc_resolve::{Resolver, ResolverOutputs};
use rustc_session::Session;
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
use rustc_session::cstore::Untracked;
use rustc_session::errors::feature_err;
use rustc_session::output::{filename_for_input, invalid_output_for_target};
use rustc_session::parse::feature_err;
use rustc_session::search_paths::PathKind;
use rustc_span::{
DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
+1 -1
View File
@@ -966,7 +966,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
let mut lint = Diag::new(dcx, level, msg!("unknown lint: `{$name}`"))
.with_arg("name", lint_id.lint.name_lower())
.with_note(msg!("the `{$name}` lint is unstable"));
rustc_session::parse::add_feature_diagnostics_for_issue(
rustc_session::errors::add_feature_diagnostics_for_issue(
&mut lint,
sess,
feature,
+1 -1
View File
@@ -306,7 +306,7 @@ impl<'a> Diagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let mut diag = Diag::new(dcx, level, "`#[track_caller]` on async functions is a no-op")
.with_span_label(self.label, "this function will not propagate the caller location");
rustc_session::parse::add_feature_diagnostics(
rustc_session::errors::add_feature_diagnostics(
&mut diag,
self.session,
sym::async_fn_track_caller,
@@ -11,9 +11,9 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, ConstStability, DefaultBodyStability, HirId, Stability};
use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic};
use rustc_session::Session;
use rustc_session::errors::feature_err_issue;
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE};
use rustc_session::lint::{DeprecatedSinceKind, Level, Lint};
use rustc_session::parse::feature_err_issue;
use rustc_span::{Span, Symbol, sym};
use tracing::debug;
+1 -1
View File
@@ -36,12 +36,12 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType;
use rustc_session::errors::feature_err;
use rustc_session::lint;
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
+1 -1
View File
@@ -6,8 +6,8 @@ use rustc_ast::{self as ast, NodeId};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};
use rustc_middle::{bug, span_bug};
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
use rustc_span::{Ident, Span, kw, sym};
+1 -1
View File
@@ -18,11 +18,11 @@ use rustc_hir::def_id::{DefId, LocalDefIdMap};
use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
use rustc_middle::span_bug;
use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::{
AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS,
PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS,
};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::LocalExpnId;
use rustc_span::{Ident, Span, Symbol, kw, sym};
+1 -1
View File
@@ -32,8 +32,8 @@ use rustc_middle::middle::resolve_bound_vars::Set1;
use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility};
use rustc_middle::{bug, span_bug};
use rustc_session::config::{CrateType, ResolveDocLinks};
use rustc_session::errors::feature_err;
use rustc_session::lint;
use rustc_session::parse::feature_err;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Spanned, Symbol, kw, respan, sym};
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
+1 -1
View File
@@ -23,11 +23,11 @@ use rustc_hir::{Attribute, StabilityLevel};
use rustc_middle::middle::stability;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::Session;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::{
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
UNUSED_MACRO_RULES, UNUSED_MACROS,
};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
+167 -2
View File
@@ -5,14 +5,179 @@ use rustc_ast::util::literal::LitError;
use rustc_errors::codes::*;
use rustc_errors::{
Diag, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, ErrorGuaranteed, Level,
MultiSpan,
MultiSpan, StashKey,
};
use rustc_feature::{GateIssue, find_feature_issue};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
use rustc_span::{Span, Symbol, sym};
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple};
use crate::Session;
use crate::lint::builtin::UNSTABLE_SYNTAX_PRE_EXPANSION;
use crate::parse::ParseSess;
/// Construct a diagnostic for a language feature error due to the given `span`.
/// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbol`.
#[track_caller]
pub fn feature_err(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
feature_err_issue(sess, feature, span, GateIssue::Language, explain)
}
/// Construct a diagnostic for a feature gate error.
///
/// 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_err`.
#[track_caller]
pub fn feature_err_issue(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
issue: GateIssue,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span()
&& let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning)
{
err.cancel()
}
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false, None);
err
}
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
#[track_caller]
pub fn feature_warn(sess: &Session, feature: Symbol, span: Span, explain: &'static 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`.
#[track_caller]
pub fn feature_warn_issue(
sess: &Session,
feature: Symbol,
span: Span,
issue: GateIssue,
explain: &'static str,
) {
let mut err = sess.dcx().struct_span_warn(span, explain);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false, None);
// Decorate this as a future-incompatibility lint as in rustc_middle::lint::lint_level
let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
let future_incompatible = lint.future_incompatible.as_ref().unwrap();
err.is_lint(lint.name_lower(), /* has_future_breakage */ false);
err.warn(lint.desc);
err.note(format!("for more information, see {}", future_incompatible.reason.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.
/// Must be a language feature!
pub fn add_feature_diagnostics<G: EmissionGuarantee>(
err: &mut Diag<'_, G>,
sess: &Session,
feature: Symbol,
) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false, None);
}
/// Adds the diagnostics for a feature to an existing error.
///
/// 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
/// `add_feature_diagnostics`.
pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
err: &mut Diag<'_, G>,
sess: &Session,
feature: Symbol,
issue: GateIssue,
feature_from_cli: bool,
inject_span: Option<Span>,
) {
if let Some(n) = find_feature_issue(feature, issue) {
err.subdiagnostic(FeatureDiagnosticForIssue { n });
}
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
if feature_from_cli {
err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
} else if let Some(span) = inject_span {
err.subdiagnostic(FeatureDiagnosticSuggestion { feature, span });
} else {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
if feature == sym::rustc_attrs {
// We're unlikely to stabilize something out of `rustc_attrs`
// without at least renaming it, so pointing out how old
// the compiler is will do little good.
} else if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
}
/// This is only used by unstable_feature_bound as it does not have issue number information for now.
/// This is basically the same as `feature_err_issue`
/// but without the feature issue note. If we can do a lookup for issue number from feature name,
/// then we should directly use `feature_err_issue` for ambiguity error of
/// `#[unstable_feature_bound]`.
#[track_caller]
pub fn feature_err_unstable_feature_bound(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span() {
if let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning) {
err.cancel()
}
}
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
if feature == sym::rustc_attrs {
// We're unlikely to stabilize something out of `rustc_attrs`
// without at least renaming it, so pointing out how old
// the compiler is will do little good.
} else if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
err
}
#[derive(Diagnostic)]
pub(crate) enum AppleDeploymentTarget {
#[diag("failed to parse deployment target specified in {$env_var}: {$error}")]
+3 -173
View File
@@ -1,7 +1,6 @@
//! Contains `ParseSess` which holds state living beyond what one `Parser` might.
//! It also serves as an input to the parser itself.
use std::str;
use std::sync::Arc;
use rustc_ast::attr::AttrIdGenerator;
@@ -11,21 +10,15 @@ use rustc_data_structures::sync::{AppendOnlyVec, DynSend, DynSync, Lock};
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
use rustc_errors::emitter::{EmitterWithNote, stderr_destination};
use rustc_errors::{
BufferedEarlyLint, ColorConfig, DecorateDiagCompat, Diag, DiagCtxt, DiagCtxtHandle,
DiagMessage, EmissionGuarantee, Level, MultiSpan, StashKey,
BufferedEarlyLint, ColorConfig, DecorateDiagCompat, Diag, DiagCtxt, DiagCtxtHandle, Level,
MultiSpan,
};
use rustc_feature::{GateIssue, find_feature_issue};
use rustc_span::edition::Edition;
use rustc_span::hygiene::ExpnId;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::{Span, Symbol, sym};
use rustc_span::{Span, Symbol};
use crate::Session;
use crate::errors::{
CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp,
FeatureDiagnosticSuggestion, FeatureGateError, SuggestUpgradeCompiler,
};
use crate::lint::builtin::UNSTABLE_SYNTAX_PRE_EXPANSION;
use crate::lint::{Lint, LintId};
/// Collected spans during parsing for places where a certain feature was
@@ -78,169 +71,6 @@ impl SymbolGallery {
}
}
// FIXME: this function now accepts `Session` instead of `ParseSess` and should be relocated
/// Construct a diagnostic for a language feature error due to the given `span`.
/// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbol`.
#[track_caller]
pub fn feature_err(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
feature_err_issue(sess, feature, span, GateIssue::Language, explain)
}
/// Construct a diagnostic for a feature gate error.
///
/// 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_err`.
#[track_caller]
pub fn feature_err_issue(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
issue: GateIssue,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span()
&& let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning)
{
err.cancel()
}
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false, None);
err
}
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
#[track_caller]
pub fn feature_warn(sess: &Session, feature: Symbol, span: Span, explain: &'static 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`.
#[track_caller]
pub fn feature_warn_issue(
sess: &Session,
feature: Symbol,
span: Span,
issue: GateIssue,
explain: &'static str,
) {
let mut err = sess.dcx().struct_span_warn(span, explain);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false, None);
// Decorate this as a future-incompatibility lint as in rustc_middle::lint::lint_level
let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
let future_incompatible = lint.future_incompatible.as_ref().unwrap();
err.is_lint(lint.name_lower(), /* has_future_breakage */ false);
err.warn(lint.desc);
err.note(format!("for more information, see {}", future_incompatible.reason.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.
/// Must be a language feature!
pub fn add_feature_diagnostics<G: EmissionGuarantee>(
err: &mut Diag<'_, G>,
sess: &Session,
feature: Symbol,
) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false, None);
}
/// Adds the diagnostics for a feature to an existing error.
///
/// 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
/// `add_feature_diagnostics`.
pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
err: &mut Diag<'_, G>,
sess: &Session,
feature: Symbol,
issue: GateIssue,
feature_from_cli: bool,
inject_span: Option<Span>,
) {
if let Some(n) = find_feature_issue(feature, issue) {
err.subdiagnostic(FeatureDiagnosticForIssue { n });
}
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
if feature_from_cli {
err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
} else if let Some(span) = inject_span {
err.subdiagnostic(FeatureDiagnosticSuggestion { feature, span });
} else {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
if feature == sym::rustc_attrs {
// We're unlikely to stabilize something out of `rustc_attrs`
// without at least renaming it, so pointing out how old
// the compiler is will do little good.
} else if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
}
/// This is only used by unstable_feature_bound as it does not have issue number information for now.
/// This is basically the same as `feature_err_issue`
/// but without the feature issue note. If we can do a lookup for issue number from feature name,
/// then we should directly use `feature_err_issue` for ambiguity error of
/// `#[unstable_feature_bound]`.
#[track_caller]
pub fn feature_err_unstable_feature_bound(
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
explain: impl Into<DiagMessage>,
) -> Diag<'_> {
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span() {
if let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning) {
err.cancel()
}
}
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
if feature == sym::rustc_attrs {
// We're unlikely to stabilize something out of `rustc_attrs`
// without at least renaming it, so pointing out how old
// the compiler is will do little good.
} else if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
err
}
/// Info about a parsing session.
pub struct ParseSess {
dcx: DiagCtxt,
+2 -2
View File
@@ -45,7 +45,7 @@ use crate::config::{
};
use crate::filesearch::FileSearch;
use crate::lint::LintId;
use crate::parse::{ParseSess, add_feature_diagnostics};
use crate::parse::ParseSess;
use crate::search_paths::SearchPath;
use crate::{errors, filesearch, lint};
@@ -282,7 +282,7 @@ impl Session {
if err.code.is_none() {
err.code(E0658);
}
add_feature_diagnostics(&mut err, self, feature);
errors::add_feature_diagnostics(&mut err, self, feature);
err
}
@@ -13,7 +13,7 @@ use rustc_infer::traits::{
};
use rustc_middle::ty::print::PrintPolyTraitPredicateExt;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _, Unnormalized};
use rustc_session::parse::feature_err_unstable_feature_bound;
use rustc_session::errors::feature_err_unstable_feature_bound;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use tracing::{debug, instrument};
@@ -14,7 +14,7 @@ use rustc_middle::ty::{
self, GenericArgsRef, Term, TermKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor,
};
use rustc_session::parse::feature_err;
use rustc_session::errors::feature_err;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{Span, sym};
use tracing::{debug, instrument, trace};
@@ -1492,7 +1492,7 @@ impl LinkCollector<'_, '_> {
Some((sp, _)) => sp,
None => item.attr_span(self.cx.tcx),
};
rustc_session::parse::feature_err(
rustc_session::errors::feature_err(
self.cx.tcx.sess,
sym::intra_doc_pointers,
span,