Add check for ui_testing via promoting parameters from `ParseSess` to `Session`

This commit is contained in:
George-lewis 2024-01-10 00:37:30 -05:00
parent b55faad314
commit 36a69e9d39
44 changed files with 188 additions and 233 deletions

View File

@ -48,7 +48,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
if !is_stable && !self.tcx.features().asm_experimental_arch {
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::asm_experimental_arch,
sp,
"inline assembly is not stable yet on this architecture",
@ -63,13 +63,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.dcx().emit_err(AttSyntaxOnlyX86 { span: sp });
}
if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
feature_err(
&self.tcx.sess.parse_sess,
sym::asm_unwind,
sp,
"the `may_unwind` option is unstable",
)
.emit();
feature_err(&self.tcx.sess, sym::asm_unwind, sp, "the `may_unwind` option is unstable")
.emit();
}
let mut clobber_abis = FxIndexMap::default();
@ -183,7 +178,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
InlineAsmOperand::Const { anon_const } => {
if !self.tcx.features().asm_const {
feature_err(
&sess.parse_sess,
sess,
sym::asm_const,
*op_sp,
"const operands for inline assembly are unstable",

View File

@ -1512,7 +1512,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(hir::CoroutineKind::Coroutine(_)) => {
if !self.tcx.features().coroutines {
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::coroutines,
span,
"yield syntax is experimental",
@ -1524,7 +1524,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
None => {
if !self.tcx.features().coroutines {
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::coroutines,
span,
"yield syntax is experimental",

View File

@ -1043,7 +1043,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
{
add_feature_diagnostics(
&mut err,
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::return_type_notation,
);
}
@ -2310,7 +2310,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::ArrayLen::Infer(self.lower_node_id(c.id), self.lower_span(c.value.span))
} else {
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::generic_arg_infer,
c.value.span,
"using `_` for array lengths is unstable",

View File

@ -17,14 +17,12 @@ use crate::errors;
macro_rules! gate {
($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain).emit();
feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit();
}
}};
($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain)
.with_help($help)
.emit();
feature_err(&$visitor.sess, sym::$feature, $span, $explain).with_help($help).emit();
}
}};
}
@ -33,7 +31,7 @@ macro_rules! gate {
macro_rules! gate_alt {
($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{
if !$has_feature && !$span.allows_unstable($name) {
feature_err(&$visitor.sess.parse_sess, $name, $span, $explain).emit();
feature_err(&$visitor.sess, $name, $span, $explain).emit();
}
}};
}
@ -45,7 +43,7 @@ macro_rules! gate_multi {
let spans: Vec<_> =
$spans.filter(|span| !span.allows_unstable(sym::$feature)).collect();
if !spans.is_empty() {
feature_err(&$visitor.sess.parse_sess, sym::$feature, spans, $explain).emit();
feature_err(&$visitor.sess, sym::$feature, spans, $explain).emit();
}
}
}};
@ -55,7 +53,7 @@ macro_rules! gate_multi {
macro_rules! gate_legacy {
($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
feature_warn(&$visitor.sess.parse_sess, sym::$feature, $span, $explain);
feature_warn(&$visitor.sess, sym::$feature, $span, $explain);
}
}};
}
@ -91,14 +89,7 @@ impl<'a> PostExpansionVisitor<'a> {
match abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
Ok(()) => (),
Err(abi::AbiDisabled::Unstable { feature, explain }) => {
feature_err_issue(
&self.sess.parse_sess,
feature,
span,
GateIssue::Language,
explain,
)
.emit();
feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit();
}
Err(abi::AbiDisabled::Unrecognized) => {
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
@ -571,13 +562,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
if let Ok(snippet) = sm.span_to_snippet(span)
&& snippet == "!"
{
feature_err(
&sess.parse_sess,
sym::never_patterns,
span,
"`!` patterns are experimental",
)
.emit();
feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental")
.emit();
} else {
let suggestion = span.shrink_to_hi();
sess.dcx().emit_err(errors::MatchArmWithNoBody { span, suggestion });

View File

@ -9,7 +9,7 @@ use rustc_macros::HashStable_Generic;
use rustc_session::config::ExpectedValues;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::parse::feature_err;
use rustc_session::{RustcVersion, Session};
use rustc_span::hygiene::Transparency;
use rustc_span::{symbol::sym, symbol::Symbol, Span};
@ -518,15 +518,15 @@ pub struct Condition {
/// Tests if a cfg-pattern matches the cfg set
pub fn cfg_matches(
cfg: &ast::MetaItem,
sess: &ParseSess,
sess: &Session,
lint_node_id: NodeId,
features: Option<&Features>,
) -> bool {
eval_condition(cfg, sess, features, &mut |cfg| {
try_gate_cfg(cfg.name, cfg.span, sess, features);
match sess.check_config.expecteds.get(&cfg.name) {
match sess.parse_sess.check_config.expecteds.get(&cfg.name) {
Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
sess.buffer_lint_with_diagnostic(
sess.parse_sess.buffer_lint_with_diagnostic(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
@ -541,8 +541,8 @@ pub fn cfg_matches(
),
);
}
None if sess.check_config.exhaustive_names => {
sess.buffer_lint_with_diagnostic(
None if sess.parse_sess.check_config.exhaustive_names => {
sess.parse_sess.buffer_lint_with_diagnostic(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
@ -555,18 +555,18 @@ pub fn cfg_matches(
}
_ => { /* not unexpected */ }
}
sess.config.contains(&(cfg.name, cfg.value))
sess.parse_sess.config.contains(&(cfg.name, cfg.value))
})
}
fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Features>) {
fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) {
let gate = find_gated_cfg(|sym| sym == name);
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
gate_cfg(gated_cfg, span, sess, feats);
}
}
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) {
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
let (cfg, feature, has_feature) = gated_cfg;
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
let explain = format!("`cfg({cfg})` is experimental and subject to change");
@ -594,11 +594,11 @@ fn parse_version(s: Symbol) -> Option<RustcVersion> {
/// evaluate individual items.
pub fn eval_condition(
cfg: &ast::MetaItem,
sess: &ParseSess,
sess: &Session,
features: Option<&Features>,
eval: &mut impl FnMut(Condition) -> bool,
) -> bool {
let dcx = &sess.dcx;
let dcx = &sess.parse_sess.dcx;
match &cfg.kind {
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
try_gate_cfg(sym::version, cfg.span, sess, features);
@ -626,7 +626,7 @@ pub fn eval_condition(
};
// See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details
if sess.assume_incomplete_release {
if sess.parse_sess.assume_incomplete_release {
RustcVersion::CURRENT > min_version
} else {
RustcVersion::CURRENT >= min_version

View File

@ -22,7 +22,7 @@ pub fn expand_cfg(
Ok(cfg) => {
let matches_cfg = attr::cfg_matches(
&cfg,
&cx.sess.parse_sess,
&cx.sess,
cx.current_expansion.lint_node_id,
Some(cx.ecfg.features),
);

View File

@ -107,7 +107,7 @@ pub fn expand_include<'cx>(
return DummyResult::any(sp);
};
// The file will be added to the code map by the parser
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
Ok(f) => f,
Err(err) => {
err.emit();
@ -179,7 +179,7 @@ pub fn expand_include_str(
let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
return DummyResult::any(sp);
};
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
Ok(f) => f,
Err(err) => {
err.emit();
@ -213,7 +213,7 @@ pub fn expand_include_bytes(
let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
return DummyResult::any(sp);
};
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
Ok(f) => f,
Err(err) => {
err.emit();

View File

@ -2860,7 +2860,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
match lib.cfg {
Some(ref cfg) => rustc_attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
None => true,
}
}

View File

@ -155,7 +155,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
Some([item]) if item.has_name(sym::linker) => {
if !tcx.features().used_with_arg {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::used_with_arg,
attr.span,
"`#[used(linker)]` is currently unstable",
@ -167,7 +167,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
Some([item]) if item.has_name(sym::compiler) => {
if !tcx.features().used_with_arg {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::used_with_arg,
attr.span,
"`#[used(compiler)]` is currently unstable",
@ -251,7 +251,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
&& !attr.span.allows_unstable(sym::closure_track_caller)
{
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::closure_track_caller,
attr.span,
"`#[track_caller]` on closures is currently unstable",
@ -304,7 +304,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// `#[target_feature]` on `main` and `start`.
} else if !tcx.features().target_feature_11 {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::target_feature_11,
attr.span,
"`#[target_feature(..)]` can only be applied to `unsafe` functions",

View File

@ -82,7 +82,7 @@ pub fn from_target_feature(
};
if !allowed {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
feature_gate.unwrap(),
item.span(),
format!("the target feature `{feature}` is currently unstable"),

View File

@ -64,7 +64,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
&ccx.tcx.sess,
sym::const_fn_floating_point_arithmetic,
span,
format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
@ -553,7 +553,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
@ -624,7 +624,7 @@ pub mod ty {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("mutable references are not allowed in {}s", ccx.const_kind()),

View File

@ -1150,7 +1150,7 @@ impl<'a> ExtCtxt<'a> {
///
/// This unifies the logic used for resolving `include_X!`.
pub fn resolve_path(
parse_sess: &ParseSess,
parse_sess: &Session,
path: impl Into<PathBuf>,
span: Span,
) -> PResult<'_, PathBuf> {
@ -1166,7 +1166,7 @@ pub fn resolve_path(
.expect("attempting to resolve a file path in an external file"),
FileName::DocTest(path, _) => path,
other => {
return Err(parse_sess.dcx.create_err(errors::ResolveRelativePath {
return Err(parse_sess.dcx().create_err(errors::ResolveRelativePath {
span,
path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(),
}));
@ -1390,7 +1390,7 @@ pub fn parse_macro_name_and_helper_attrs(
/// asserts in old versions of those crates and their wide use in the ecosystem.
/// See issue #73345 for more details.
/// FIXME(#73933): Remove this eventually.
fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) -> bool {
let name = item.ident.name;
if name == sym::ProceduralMasqueradeDummyType {
if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
@ -1418,7 +1418,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
};
if crate_matches {
sess.buffer_lint_with_diagnostic(
sess.parse_sess.buffer_lint_with_diagnostic(
PROC_MACRO_BACK_COMPAT,
item.ident.span,
ast::CRATE_NODE_ID,
@ -1439,7 +1439,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
false
}
pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &ParseSess) -> bool {
pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) -> bool {
let item = match ann {
Annotatable::Item(item) => item,
Annotatable::Stmt(stmt) => match &stmt.kind {
@ -1451,7 +1451,7 @@ pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &P
pretty_printing_compatibility_hack(item, sess)
}
pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) -> bool {
let item = match nt {
Nonterminal::NtItem(item) => item,
Nonterminal::NtStmt(stmt) => match &stmt.kind {

View File

@ -256,12 +256,7 @@ impl<'a> StripUnconfigured<'a> {
);
}
if !attr::cfg_matches(
&cfg_predicate,
&self.sess.parse_sess,
self.lint_node_id,
self.features,
) {
if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {
return vec![];
}
@ -369,12 +364,7 @@ impl<'a> StripUnconfigured<'a> {
};
(
parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| {
attr::cfg_matches(
meta_item,
&self.sess.parse_sess,
self.lint_node_id,
self.features,
)
attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features)
}),
Some(meta_item),
)
@ -385,7 +375,7 @@ impl<'a> StripUnconfigured<'a> {
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
if self.features.is_some_and(|features| !features.stmt_expr_attributes) {
let mut err = feature_err(
&self.sess.parse_sess,
&self.sess,
sym::stmt_expr_attributes,
attr.span,
"attributes on expressions are experimental",

View File

@ -30,8 +30,8 @@ use rustc_parse::parser::{
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::Limit;
use rustc_session::parse::feature_err;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{FileName, LocalExpnId, Span};
@ -800,7 +800,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
return;
}
feature_err(
&self.cx.sess.parse_sess,
&self.cx.sess,
sym::proc_macro_hygiene,
span,
format!("custom attributes cannot be applied to {kind}"),
@ -810,7 +810,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
struct GateProcMacroInput<'a> {
parse_sess: &'a ParseSess,
sess: &'a Session,
}
impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
@ -820,7 +820,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
{
feature_err(
self.parse_sess,
self.sess,
sym::proc_macro_hygiene,
item.span,
"non-inline modules in proc macro input are unstable",
@ -835,8 +835,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
if !self.cx.ecfg.features.proc_macro_hygiene {
annotatable
.visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
annotatable.visit_with(&mut GateProcMacroInput { sess: &self.cx.sess });
}
}

View File

@ -477,14 +477,14 @@ pub fn compile_declarative_macro(
let tt = mbe::quoted::parse(
&TokenStream::new(vec![tt.clone()]),
true,
&sess.parse_sess,
sess,
def.id,
features,
edition,
)
.pop()
.unwrap();
valid &= check_lhs_nt_follows(&sess.parse_sess, def, &tt);
valid &= check_lhs_nt_follows(sess, def, &tt);
return tt;
}
sess.dcx().span_bug(def.span, "wrong-structured lhs")
@ -501,7 +501,7 @@ pub fn compile_declarative_macro(
return mbe::quoted::parse(
&TokenStream::new(vec![tt.clone()]),
false,
&sess.parse_sess,
sess,
def.id,
features,
edition,
@ -516,12 +516,12 @@ pub fn compile_declarative_macro(
};
for rhs in &rhses {
valid &= check_rhs(&sess.parse_sess, rhs);
valid &= check_rhs(sess, rhs);
}
// don't abort iteration early, so that errors for multiple lhses can be reported
for lhs in &lhses {
valid &= check_lhs_no_empty_seq(&sess.parse_sess, slice::from_ref(lhs));
valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs));
}
valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
@ -588,21 +588,21 @@ pub fn compile_declarative_macro(
(mk_syn_ext(expander), rule_spans)
}
fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
fn check_lhs_nt_follows(sess: &Session, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
// lhs is going to be like TokenTree::Delimited(...), where the
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
if let mbe::TokenTree::Delimited(.., delimited) = lhs {
check_matcher(sess, def, &delimited.tts)
} else {
let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
sess.dcx.span_err(lhs.span(), msg);
sess.dcx().span_err(lhs.span(), msg);
false
}
// we don't abort on errors on rejection, the driver will do that for us
// after parsing/expansion. we can report every error in every macro this way.
}
fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool {
fn is_empty_token_tree(sess: &Session, seq: &mbe::SequenceRepetition) -> bool {
if seq.separator.is_some() {
false
} else {
@ -621,7 +621,7 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
iter.next();
}
let span = t.span.to(now.span);
sess.dcx.span_note(span, "doc comments are ignored in matcher position");
sess.dcx().span_note(span, "doc comments are ignored in matcher position");
}
mbe::TokenTree::Sequence(_, sub_seq)
if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
@ -635,7 +635,7 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
/// Checks that the lhs contains no repetition which could match an empty token
/// tree, because then the matcher would hang indefinitely.
fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> bool {
use mbe::TokenTree;
for tt in tts {
match tt {
@ -651,7 +651,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
TokenTree::Sequence(span, seq) => {
if is_empty_token_tree(sess, seq) {
let sp = span.entire();
sess.dcx.span_err(sp, "repetition matches empty token tree");
sess.dcx().span_err(sp, "repetition matches empty token tree");
return false;
}
if !check_lhs_no_empty_seq(sess, &seq.tts) {
@ -664,22 +664,22 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
true
}
fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> bool {
match *rhs {
mbe::TokenTree::Delimited(..) => return true,
_ => {
sess.dcx.span_err(rhs.span(), "macro rhs must be delimited");
sess.dcx().span_err(rhs.span(), "macro rhs must be delimited");
}
}
false
}
fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
fn check_matcher(sess: &Session, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
let first_sets = FirstSets::new(matcher);
let empty_suffix = TokenSet::empty();
let err = sess.dcx.err_count();
let err = sess.dcx().err_count();
check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
err == sess.dcx.err_count()
err == sess.dcx().err_count()
}
fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
@ -1014,7 +1014,7 @@ impl<'tt> TokenSet<'tt> {
// Requires that `first_sets` is pre-computed for `matcher`;
// see `FirstSets::new`.
fn check_matcher_core<'tt>(
sess: &ParseSess,
sess: &Session,
def: &ast::Item,
first_sets: &FirstSets<'tt>,
matcher: &'tt [mbe::TokenTree],
@ -1139,7 +1139,7 @@ fn check_matcher_core<'tt>(
name,
Some(NonterminalKind::PatParam { inferred: false }),
));
sess.buffer_lint_with_diagnostic(
sess.parse_sess.buffer_lint_with_diagnostic(
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
span,
ast::CRATE_NODE_ID,
@ -1158,7 +1158,7 @@ fn check_matcher_core<'tt>(
};
let sp = next_token.span();
let mut err = sess.dcx.struct_span_err(
let mut err = sess.dcx().struct_span_err(
sp,
format!(
"`${name}:{frag}` {may_be} followed by `{next}`, which \
@ -1172,7 +1172,7 @@ fn check_matcher_core<'tt>(
err.span_label(sp, format!("not allowed after `{kind}` fragments"));
if kind == NonterminalKind::PatWithOr
&& sess.edition.at_least_rust_2021()
&& sess.parse_sess.edition.at_least_rust_2021()
&& next_token.is_token(&BinOp(token::BinOpToken::Or))
{
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(

View File

@ -5,7 +5,8 @@ use rustc_ast::token::{self, Delimiter, Token};
use rustc_ast::{tokenstream, NodeId};
use rustc_ast_pretty::pprust;
use rustc_feature::Features;
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::edition::Edition;
@ -38,7 +39,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
pub(super) fn parse(
input: &tokenstream::TokenStream,
parsing_patterns: bool,
sess: &ParseSess,
sess: &Session,
node_id: NodeId,
features: &Features,
edition: Edition,
@ -84,7 +85,7 @@ pub(super) fn parse(
"invalid fragment specifier `{}`",
frag.name
);
sess.dcx
sess.dcx()
.struct_span_err(span, msg)
.with_help(VALID_FRAGMENT_NAMES_MSG)
.emit();
@ -113,7 +114,7 @@ pub(super) fn parse(
}
/// Asks for the `macro_metavar_expr` feature if it is not already declared
fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess, span: Span) {
fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) {
if !features.macro_metavar_expr {
let msg = "meta-variable expressions are unstable";
feature_err(sess, sym::macro_metavar_expr, span, msg).emit();
@ -138,7 +139,7 @@ fn parse_tree<'a>(
tree: &'a tokenstream::TokenTree,
outer_trees: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
parsing_patterns: bool,
sess: &ParseSess,
sess: &Session,
node_id: NodeId,
features: &Features,
edition: Edition,
@ -174,7 +175,8 @@ fn parse_tree<'a>(
// The delimiter is `{`. This indicates the beginning
// of a meta-variable expression (e.g. `${count(ident)}`).
// Try to parse the meta-variable expression.
match MetaVarExpr::parse(tts, delim_span.entire(), sess) {
match MetaVarExpr::parse(tts, delim_span.entire(), &sess.parse_sess)
{
Err(err) => {
err.emit();
// Returns early the same read `$` to avoid spanning
@ -195,7 +197,7 @@ fn parse_tree<'a>(
_ => {
let tok = pprust::token_kind_to_string(&token::OpenDelim(delim));
let msg = format!("expected `(` or `{{`, found `{tok}`");
sess.dcx.span_err(delim_span.entire(), msg);
sess.dcx().span_err(delim_span.entire(), msg);
}
}
}
@ -244,7 +246,7 @@ fn parse_tree<'a>(
Some(tokenstream::TokenTree::Token(token, _)) => {
let msg =
format!("expected identifier, found `{}`", pprust::token_to_string(token),);
sess.dcx.span_err(token.span, msg);
sess.dcx().span_err(token.span, msg);
TokenTree::MetaVar(token.span, Ident::empty())
}
@ -313,7 +315,7 @@ fn parse_kleene_op<'a>(
fn parse_sep_and_kleene_op<'a>(
input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
span: Span,
sess: &ParseSess,
sess: &Session,
) -> (Option<Token>, KleeneToken) {
// We basically look at two token trees here, denoted as #1 and #2 below
let span = match parse_kleene_op(input, span) {
@ -325,7 +327,7 @@ fn parse_sep_and_kleene_op<'a>(
// #2 is the `?` Kleene op, which does not take a separator (error)
Ok(Ok((KleeneOp::ZeroOrOne, span))) => {
// Error!
sess.dcx.span_err(
sess.dcx().span_err(
token.span,
"the `?` macro repetition operator does not take a separator",
);
@ -346,7 +348,7 @@ fn parse_sep_and_kleene_op<'a>(
};
// If we ever get to this point, we have experienced an "unexpected token" error
sess.dcx.span_err(span, "expected one of: `*`, `+`, or `?`");
sess.dcx().span_err(span, "expected one of: `*`, `+`, or `?`");
// Return a dummy
(None, KleeneToken::new(KleeneOp::ZeroOrMore, span))
@ -355,9 +357,10 @@ fn parse_sep_and_kleene_op<'a>(
// `$$` or a meta-variable is the lhs of a macro but shouldn't.
//
// For example, `macro_rules! foo { ( ${length()} ) => {} }`
fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) {
sess.dcx.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
sess.dcx.span_note(
fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &Session, token: &Token) {
sess.dcx()
.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
sess.dcx().span_note(
token.span,
"`$$` and meta-variable expressions are not allowed inside macro parameter definitions",
);

View File

@ -119,7 +119,7 @@ impl MultiItemModifier for DeriveProcMacro {
// We need special handling for statement items
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
let is_stmt = matches!(item, Annotatable::Stmt(..));
let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess);
let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess);
let input = if hack {
let nt = match item {
Annotatable::Item(item) => token::NtItem(item),

View File

@ -258,7 +258,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
// represented as a delimited group.
// FIXME: It needs to be removed, but there are some
// compatibility issues (see #73345).
if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.sess()) {
if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.ecx.sess) {
trees.extend(Self::from_internal((stream, rustc)));
} else {
trees.push(TokenTree::Group(Group {

View File

@ -59,7 +59,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if trait_segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar {
// For now, require that parenthetical notation be used only with `Fn()` etc.
feature_err(
&self.tcx().sess.parse_sess,
&self.tcx().sess,
sym::unboxed_closures,
span,
"parenthetical notation is only stable when used with `Fn`-family traits",
@ -75,7 +75,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if trait_segment.args().parenthesized != hir::GenericArgsParentheses::ParenSugar {
// For now, require that parenthetical notation be used only with `Fn()` etc.
let mut err = feature_err(
&sess.parse_sess,
sess,
sym::unboxed_closures,
span,
"the precise format of `Fn`-family traits' type parameters is subject to change",

View File

@ -996,7 +996,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
if adt.is_union() && !tcx.features().transparent_unions {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::transparent_unions,
tcx.def_span(adt.did()),
"transparent unions are unstable",
@ -1128,7 +1128,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
if !tcx.features().repr128 {
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::repr128,
tcx.def_span(def_id),
"repr with 128-bit type is unstable",

View File

@ -293,7 +293,7 @@ fn default_body_is_unstable(
rustc_session::parse::add_feature_diagnostics_for_issue(
&mut err,
&tcx.sess.parse_sess,
&tcx.sess,
feature,
rustc_feature::GateIssue::Library(issue),
false,

View File

@ -1591,7 +1591,7 @@ fn check_method_receiver<'tcx>(
return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
// Report error; would have worked with `arbitrary_self_types`.
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::arbitrary_self_types,
span,
format!(

View File

@ -1189,12 +1189,13 @@ 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_session::parse::feature_err(
&self.tcx.sess.parse_sess,
sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.ident.span,
"anonymous lifetimes in `impl Trait` are unstable",
);
let mut diag: rustc_errors::DiagnosticBuilder<'_> =
rustc_session::parse::feature_err(
&self.tcx.sess,
sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.ident.span,
"anonymous lifetimes in `impl Trait` are unstable",
);
if let Some(generics) =
self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id)

View File

@ -639,7 +639,7 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
use rustc_session::parse::feature_err;
use rustc_span::symbol::sym;
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::inherent_associated_types,
span,
"inherent associated types are unstable",

View File

@ -133,13 +133,8 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
(false, true) => {
feature_err(
&tcx.sess.parse_sess,
sym::extended_varargs_abi_support,
span,
UNSTABLE_EXPLAIN,
)
.emit();
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
.emit();
CONVENTIONS_STABLE
}

View File

@ -704,7 +704,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::unsized_tuple_coercion,
self.cause.span,
"unsized tuple coercion is not stable enough for use and is subject to change",

View File

@ -1865,7 +1865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt);
if self.tcx.sess.is_nightly_build() && same_adt {
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::type_changing_struct_update,
base_expr.span,
"type changing struct updating is experimental",
@ -3262,7 +3262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !self.tcx.features().offset_of_enum {
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::offset_of_enum,
ident.span,
"using enums in offset_of is experimental",

View File

@ -1306,10 +1306,7 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
cx.emit_spanned_lint(
UNGATED_ASYNC_FN_TRACK_CALLER,
attr.span,
BuiltinUngatedAsyncFnTrackCaller {
label: span,
parse_sess: &cx.tcx.sess.parse_sess,
},
BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess },
);
}
}

View File

@ -786,7 +786,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
if let ast::LitKind::Str(rationale, _) = name_value.kind {
if !self.features.lint_reasons {
feature_err(
&self.sess.parse_sess,
&self.sess,
sym::lint_reasons,
item.span,
"lint reasons are experimental",
@ -1074,7 +1074,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
lint.note(fluent::lint_note);
rustc_session::parse::add_feature_diagnostics_for_issue(
lint,
&self.sess.parse_sess,
&self.sess,
feature,
GateIssue::Language,
lint_from_cli,

View File

@ -13,7 +13,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::{
inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
};
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
use crate::{
@ -235,7 +235,7 @@ pub struct BuiltinUnstableFeatures;
// lint_ungated_async_fn_track_caller
pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
pub label: Span,
pub parse_sess: &'a ParseSess,
pub session: &'a Session,
}
impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
@ -243,7 +243,7 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
diag.span_label(self.label, fluent::lint_label);
rustc_session::parse::add_feature_diagnostics(
diag,
self.parse_sess,
self.session,
sym::async_fn_track_caller,
);
}

View File

@ -82,7 +82,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>
pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
match lib.cfg {
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
Some(ref cfg) => attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
None => true,
}
}
@ -163,7 +163,7 @@ impl<'tcx> Collector<'tcx> {
"link-arg" => {
if !features.link_arg_attribute {
feature_err(
&sess.parse_sess,
sess,
sym::link_arg_attribute,
span,
"link kind `link-arg` is unstable",
@ -206,13 +206,8 @@ impl<'tcx> Collector<'tcx> {
continue;
};
if !features.link_cfg {
feature_err(
&sess.parse_sess,
sym::link_cfg,
item.span(),
"link cfg is unstable",
)
.emit();
feature_err(sess, sym::link_cfg, item.span(), "link cfg is unstable")
.emit();
}
cfg = Some(link_cfg.clone());
}
@ -277,7 +272,7 @@ impl<'tcx> Collector<'tcx> {
macro report_unstable_modifier($feature: ident) {
if !features.$feature {
feature_err(
&sess.parse_sess,
sess,
sym::$feature,
span,
format!("linking modifier `{modifier}` is unstable"),

View File

@ -116,8 +116,7 @@ pub fn report_unstable(
if is_soft {
soft_handler(SOFT_UNSTABLE, span, msg)
} else {
let mut err =
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), msg);
let mut err = feature_err_issue(sess, feature, span, GateIssue::Library(issue), msg);
if let Some((inner_types, msg, sugg, applicability)) = suggestion {
err.span_suggestion(inner_types, msg, sugg, applicability);
}

View File

@ -1170,7 +1170,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
sym::rust_logo => {
if !self.tcx.features().rustdoc_internals {
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::rustdoc_internals,
meta.span(),
"the `#[doc(rust_logo)]` attribute is used for Rust branding",
@ -1815,7 +1815,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
(target, self.tcx.features().fn_align)
{
feature_err(
&self.tcx.sess.parse_sess,
&self.tcx.sess,
sym::fn_align,
hint.span(),
"`repr(align)` attributes on functions are unstable",

View File

@ -147,7 +147,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
[missing_primary, ref missing_secondary @ ..] => {
let msg =
format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, msg);
let mut err = feature_err(&tcx.sess, *missing_primary, span, msg);
// If multiple feature gates would be required to enable this expression, include
// them as help messages. Don't emit a separate error for each missing feature gate.

View File

@ -45,14 +45,13 @@ impl DebuggerVisualizerCollector<'_> {
}
};
let file =
match resolve_path(&self.sess.parse_sess, visualizer_path.as_str(), attr.span) {
Ok(file) => file,
Err(err) => {
err.emit();
return;
}
};
let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
Ok(file) => file,
Err(err) => {
err.emit();
return;
}
};
match std::fs::read(&file) {
Ok(contents) => {

View File

@ -135,7 +135,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
if main_def.is_import && !tcx.features().imported_main {
let span = main_def.span;
feature_err(
&tcx.sess.parse_sess,
&tcx.sess,
sym::imported_main,
span,
"using an imported function as entry point `main` is experimental",

View File

@ -594,13 +594,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if soft_custom_inner_attributes_gate {
self.tcx.sess.parse_sess.buffer_lint(SOFT_UNSTABLE, path.span, node_id, msg);
} else {
feature_err(
&self.tcx.sess.parse_sess,
sym::custom_inner_attributes,
path.span,
msg,
)
.emit();
feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
}
}

View File

@ -25,7 +25,7 @@ session_feature_diagnostic_help =
add `#![feature({$feature})]` to the crate attributes to enable
session_feature_suggest_upgrade_compiler =
this compiler is version {$version} built on {$date}, consider upgrading?
this compiler was built on {$date}; consider upgrading it if it is out of date
session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions

View File

@ -1,6 +1,5 @@
use std::num::NonZeroU32;
use crate::parse::ParseSess;
use rustc_ast::token;
use rustc_ast::util::literal::LitError;
use rustc_errors::{
@ -10,6 +9,8 @@ use rustc_macros::Diagnostic;
use rustc_span::{BytePos, Span, Symbol};
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
use crate::parse::ParseSess;
pub struct FeatureGateError {
pub span: MultiSpan,
pub explain: DiagnosticMessage,
@ -33,16 +34,18 @@ pub struct FeatureDiagnosticForIssue {
#[derive(Subdiagnostic)]
#[note(session_feature_suggest_upgrade_compiler)]
pub struct SuggestUpgradeCompiler {
version: &'static str,
date: &'static str,
}
impl SuggestUpgradeCompiler {
pub fn new() -> Self {
let version = option_env!("CFG_VERSION").unwrap_or("unknown");
let date = option_env!("CFG_VER_DATE").unwrap_or("unknown");
pub fn ui_testing() -> Self {
Self { date: "YYYY-MM-DD" }
}
Self { version, date }
pub fn new() -> Option<Self> {
let date = option_env!("CFG_VER_DATE")?;
Some(Self { date })
}
}

View File

@ -9,6 +9,7 @@ use crate::errors::{
use crate::lint::{
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
};
use crate::Session;
use rustc_ast::node_id::NodeId;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
@ -80,7 +81,7 @@ impl SymbolGallery {
/// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbols`.
#[track_caller]
pub fn feature_err(
sess: &ParseSess,
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
explain: impl Into<DiagnosticMessage>,
@ -94,7 +95,7 @@ pub fn feature_err(
/// Almost always, you want to use this for a language feature. If so, prefer `feature_err`.
#[track_caller]
pub fn feature_err_issue(
sess: &ParseSess,
sess: &Session,
feature: Symbol,
span: impl Into<MultiSpan>,
issue: GateIssue,
@ -104,12 +105,14 @@ pub fn feature_err_issue(
// 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_diagnostic(span, StashKey::EarlySyntaxWarning) {
if let Some(err) = sess.parse_sess.dcx.steal_diagnostic(span, StashKey::EarlySyntaxWarning)
{
err.cancel()
}
}
let mut err = sess.dcx.create_err(FeatureGateError { span, explain: explain.into() });
let mut err =
sess.parse_sess.dcx.create_err(FeatureGateError { span, explain: explain.into() });
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
err
}
@ -118,7 +121,7 @@ pub fn feature_err_issue(
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
#[track_caller]
pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'static str) {
pub fn feature_warn(sess: &Session, feature: Symbol, span: Span, explain: &'static str) {
feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
}
@ -132,13 +135,13 @@ pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'st
#[allow(rustc::untranslatable_diagnostic)]
#[track_caller]
pub fn feature_warn_issue(
sess: &ParseSess,
sess: &Session,
feature: Symbol,
span: Span,
issue: GateIssue,
explain: &'static str,
) {
let mut err = sess.dcx.struct_span_warn(span, explain);
let mut err = sess.parse_sess.dcx.struct_span_warn(span, explain);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
// Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
@ -153,7 +156,7 @@ pub fn feature_warn_issue(
}
/// Adds the diagnostics for a feature to an existing error.
pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) {
pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &Session, feature: Symbol) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false);
}
@ -164,7 +167,7 @@ pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature:
/// `add_feature_diagnostics`.
pub fn add_feature_diagnostics_for_issue(
err: &mut Diagnostic,
sess: &ParseSess,
sess: &Session,
feature: Symbol,
issue: GateIssue,
feature_from_cli: bool,
@ -174,14 +177,18 @@ pub fn add_feature_diagnostics_for_issue(
}
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
if sess.parse_sess.unstable_features.is_nightly_build() {
if feature_from_cli {
err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
} else {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
err.subdiagnostic(SuggestUpgradeCompiler::new());
if sess.opts.unstable_opts.ui_testing {
err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
} else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
err.subdiagnostic(suggestion);
}
}
}

View File

@ -318,7 +318,7 @@ impl Session {
if err.code.is_none() {
err.code(error_code!(E0658));
}
add_feature_diagnostics(&mut err, &self.parse_sess, feature);
add_feature_diagnostics(&mut err, self, feature);
err
}

View File

@ -408,7 +408,7 @@ impl<'tcx> OnUnimplementedDirective {
.ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?
.meta_item()
.ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| {
if let Some(value) = cfg.value
&& let Err(guar) = parse_value(value, cfg.span)
{
@ -682,31 +682,22 @@ impl<'tcx> OnUnimplementedDirective {
for command in self.subcommands.iter().chain(Some(self)).rev() {
if let Some(ref condition) = command.condition
&& !attr::eval_condition(
condition,
&tcx.sess.parse_sess,
Some(tcx.features()),
&mut |cfg| {
let value = cfg.value.map(|v| {
// `with_no_visible_paths` is also used when generating the options,
// so we need to match it here.
ty::print::with_no_visible_paths!(
OnUnimplementedFormatString {
symbol: v,
span: cfg.span,
is_diagnostic_namespace_variant: false
}
.format(
tcx,
trait_ref,
&options_map
)
)
});
&& !attr::eval_condition(condition, &tcx.sess, Some(tcx.features()), &mut |cfg| {
let value = cfg.value.map(|v| {
// `with_no_visible_paths` is also used when generating the options,
// so we need to match it here.
ty::print::with_no_visible_paths!(
OnUnimplementedFormatString {
symbol: v,
span: cfg.span,
is_diagnostic_namespace_variant: false
}
.format(tcx, trait_ref, &options_map)
)
});
options.contains(&(cfg.name, value))
},
)
options.contains(&(cfg.name, value))
})
{
debug!("evaluate: skipping {:?} due to condition", command);
continue;

View File

@ -65,9 +65,10 @@ pub(crate) fn look_for_custom_classes<'tcx>(cx: &DocContext<'tcx>, item: &Item)
if !tests.custom_classes_found.is_empty() {
let span = item.attr_span(cx.tcx);
let sess = &cx.tcx.sess.parse_sess;
let mut err =
sess.dcx.struct_span_warn(span, "custom classes in code blocks will change behaviour");
let sess = &cx.tcx.sess;
let mut err = sess
.dcx()
.struct_span_warn(span, "custom classes in code blocks will change behaviour");
add_feature_diagnostics_for_issue(
&mut err,
sess,

View File

@ -1223,7 +1223,7 @@ impl LinkCollector<'_, '_> {
)
.unwrap_or_else(|| item.attr_span(self.cx.tcx));
rustc_session::parse::feature_err(
&self.cx.tcx.sess.parse_sess,
&self.cx.tcx.sess,
sym::intra_doc_pointers,
span,
"linking to associated items of raw pointers is experimental",