1
Fork 0

Remove sess field from LoweringContext.

This commit is contained in:
Camille GILLOT 2022-05-02 20:32:17 +02:00
parent 74be945820
commit 8fc3deb1b4
6 changed files with 69 additions and 57 deletions

View file

@ -24,9 +24,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> &'hir hir::InlineAsm<'hir> { ) -> &'hir hir::InlineAsm<'hir> {
// Rustdoc needs to support asm! from foreign architectures: don't try // Rustdoc needs to support asm! from foreign architectures: don't try
// lowering the register constraints in this case. // lowering the register constraints in this case.
let asm_arch = if self.sess.opts.actually_rustdoc { None } else { self.sess.asm_arch }; let asm_arch =
if asm_arch.is_none() && !self.sess.opts.actually_rustdoc { if self.tcx.sess.opts.actually_rustdoc { None } else { self.tcx.sess.asm_arch };
struct_span_err!(self.sess, sp, E0472, "inline assembly is unsupported on this target") if asm_arch.is_none() && !self.tcx.sess.opts.actually_rustdoc {
struct_span_err!(
self.tcx.sess,
sp,
E0472,
"inline assembly is unsupported on this target"
)
.emit(); .emit();
} }
if let Some(asm_arch) = asm_arch { if let Some(asm_arch) = asm_arch {
@ -40,9 +46,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| asm::InlineAsmArch::RiscV32 | asm::InlineAsmArch::RiscV32
| asm::InlineAsmArch::RiscV64 | asm::InlineAsmArch::RiscV64
); );
if !is_stable && !self.sess.features_untracked().asm_experimental_arch { if !is_stable && !self.tcx.features().asm_experimental_arch {
feature_err( feature_err(
&self.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::asm_experimental_arch, sym::asm_experimental_arch,
sp, sp,
"inline assembly is not stable yet on this architecture", "inline assembly is not stable yet on this architecture",
@ -52,17 +58,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)) && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
&& !self.sess.opts.actually_rustdoc && !self.tcx.sess.opts.actually_rustdoc
{ {
self.sess self.tcx
.sess
.struct_span_err(sp, "the `att_syntax` option is only supported on x86") .struct_span_err(sp, "the `att_syntax` option is only supported on x86")
.emit(); .emit();
} }
if asm.options.contains(InlineAsmOptions::MAY_UNWIND) if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
&& !self.sess.features_untracked().asm_unwind
{
feature_err( feature_err(
&self.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::asm_unwind, sym::asm_unwind,
sp, sp,
"the `may_unwind` option is unstable", "the `may_unwind` option is unstable",
@ -73,12 +78,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut clobber_abis = FxHashMap::default(); let mut clobber_abis = FxHashMap::default();
if let Some(asm_arch) = asm_arch { if let Some(asm_arch) = asm_arch {
for (abi_name, abi_span) in &asm.clobber_abis { for (abi_name, abi_span) in &asm.clobber_abis {
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) { match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
Ok(abi) => { Ok(abi) => {
// If the abi was already in the list, emit an error // If the abi was already in the list, emit an error
match clobber_abis.get(&abi) { match clobber_abis.get(&abi) {
Some((prev_name, prev_sp)) => { Some((prev_name, prev_sp)) => {
let mut err = self.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
*abi_span, *abi_span,
&format!("`{}` ABI specified multiple times", prev_name), &format!("`{}` ABI specified multiple times", prev_name),
); );
@ -86,7 +91,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Multiple different abi names may actually be the same ABI // Multiple different abi names may actually be the same ABI
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI // If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
let source_map = self.sess.source_map(); let source_map = self.tcx.sess.source_map();
if source_map.span_to_snippet(*prev_sp) if source_map.span_to_snippet(*prev_sp)
!= source_map.span_to_snippet(*abi_span) != source_map.span_to_snippet(*abi_span)
{ {
@ -101,7 +106,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
Err(&[]) => { Err(&[]) => {
self.sess self.tcx
.sess
.struct_span_err( .struct_span_err(
*abi_span, *abi_span,
"`clobber_abi` is not supported on this target", "`clobber_abi` is not supported on this target",
@ -109,8 +115,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.emit(); .emit();
} }
Err(supported_abis) => { Err(supported_abis) => {
let mut err = let mut err = self
self.sess.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`"); .tcx
.sess
.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
let mut abis = format!("`{}`", supported_abis[0]); let mut abis = format!("`{}`", supported_abis[0]);
for m in &supported_abis[1..] { for m in &supported_abis[1..] {
let _ = write!(abis, ", `{}`", m); let _ = write!(abis, ", `{}`", m);
@ -128,7 +136,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Lower operands to HIR. We use dummy register classes if an error // Lower operands to HIR. We use dummy register classes if an error
// occurs during lowering because we still need to be able to produce a // occurs during lowering because we still need to be able to produce a
// valid HIR. // valid HIR.
let sess = self.sess; let sess = self.tcx.sess;
let mut operands: Vec<_> = asm let mut operands: Vec<_> = asm
.operands .operands
.iter() .iter()
@ -184,9 +192,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
InlineAsmOperand::Const { ref anon_const } => { InlineAsmOperand::Const { ref anon_const } => {
if !self.sess.features_untracked().asm_const { if !self.tcx.features().asm_const {
feature_err( feature_err(
&self.sess.parse_sess, &sess.parse_sess,
sym::asm_const, sym::asm_const,
*op_sp, *op_sp,
"const operands for inline assembly are unstable", "const operands for inline assembly are unstable",
@ -198,9 +206,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
InlineAsmOperand::Sym { ref sym } => { InlineAsmOperand::Sym { ref sym } => {
if !self.sess.features_untracked().asm_sym { if !self.tcx.features().asm_sym {
feature_err( feature_err(
&self.sess.parse_sess, &sess.parse_sess,
sym::asm_sym, sym::asm_sym,
*op_sp, *op_sp,
"sym operands for inline assembly are unstable", "sym operands for inline assembly are unstable",

View file

@ -159,9 +159,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span, span,
kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)), kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)),
}); });
if !self.sess.features_untracked().let_else { if !self.tcx.features().let_else {
feature_err( feature_err(
&self.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::let_else, sym::let_else,
local.span, local.span,
"`let...else` statements are unstable", "`let...else` statements are unstable",

View file

@ -46,7 +46,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = self.lower_node_id(e.id); let hir_id = self.lower_node_id(e.id);
return hir::Expr { hir_id, kind, span: self.lower_span(e.span) }; return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
} else { } else {
self.sess self.tcx.sess
.struct_span_err( .struct_span_err(
e.span, e.span,
"#[rustc_box] requires precisely one argument \ "#[rustc_box] requires precisely one argument \
@ -207,8 +207,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims) self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
} }
ExprKind::Underscore => { ExprKind::Underscore => {
self.sess self.tcx
.struct_span_err( .sess.struct_span_err(
e.span, e.span,
"in expressions, `_` can only be used on the left-hand side of an assignment", "in expressions, `_` can only be used on the left-hand side of an assignment",
) )
@ -245,7 +245,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
let rest = match &se.rest { let rest = match &se.rest {
StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Base(e) => Some(self.lower_expr(e)),
StructRest::Rest(sp) => { StructRest::Rest(sp) => {
self.sess self.tcx
.sess
.struct_span_err(*sp, "base expression required after `..`") .struct_span_err(*sp, "base expression required after `..`")
.span_label(*sp, "add a base expression here") .span_label(*sp, "add a base expression here")
.emit(); .emit();
@ -474,7 +475,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else { } else {
let try_span = this.mark_span_with_reason( let try_span = this.mark_span_with_reason(
DesugaringKind::TryBlock, DesugaringKind::TryBlock,
this.sess.source_map().end_point(body.span), this.tcx.sess.source_map().end_point(body.span),
this.allow_try_trait.clone(), this.allow_try_trait.clone(),
); );
@ -653,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(hir::GeneratorKind::Async(_)) => {} Some(hir::GeneratorKind::Async(_)) => {}
Some(hir::GeneratorKind::Gen) | None => { Some(hir::GeneratorKind::Gen) | None => {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.sess, self.tcx.sess,
dot_await_span, dot_await_span,
E0728, E0728,
"`await` is only allowed inside `async` functions and blocks" "`await` is only allowed inside `async` functions and blocks"
@ -878,7 +879,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(hir::GeneratorKind::Gen) => { Some(hir::GeneratorKind::Gen) => {
if decl.inputs.len() > 1 { if decl.inputs.len() > 1 {
struct_span_err!( struct_span_err!(
self.sess, self.tcx.sess,
fn_decl_span, fn_decl_span,
E0628, E0628,
"too many parameters for a generator (expected 0 or 1 parameters)" "too many parameters for a generator (expected 0 or 1 parameters)"
@ -892,7 +893,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
None => { None => {
if movability == Movability::Static { if movability == Movability::Static {
struct_span_err!(self.sess, fn_decl_span, E0697, "closures cannot be static") struct_span_err!(
self.tcx.sess,
fn_decl_span,
E0697,
"closures cannot be static"
)
.emit(); .emit();
} }
None None
@ -916,7 +922,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// FIXME(cramertj): allow `async` non-`move` closures with arguments. // FIXME(cramertj): allow `async` non-`move` closures with arguments.
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() { if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
struct_span_err!( struct_span_err!(
this.sess, this.tcx.sess,
fn_decl_span, fn_decl_span,
E0708, E0708,
"`async` non-`move` closures with parameters are not currently supported", "`async` non-`move` closures with parameters are not currently supported",
@ -1163,7 +1169,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
let fields_omitted = match &se.rest { let fields_omitted = match &se.rest {
StructRest::Base(e) => { StructRest::Base(e) => {
self.sess self.tcx
.sess
.struct_span_err( .struct_span_err(
e.span, e.span,
"functional record updates are not allowed in destructuring \ "functional record updates are not allowed in destructuring \
@ -1371,7 +1378,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(hir::GeneratorKind::Gen) => {} Some(hir::GeneratorKind::Gen) => {}
Some(hir::GeneratorKind::Async(_)) => { Some(hir::GeneratorKind::Async(_)) => {
struct_span_err!( struct_span_err!(
self.sess, self.tcx.sess,
span, span,
E0727, E0727,
"`async` generators are not yet supported" "`async` generators are not yet supported"
@ -1516,7 +1523,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span, span,
self.allow_try_trait.clone(), self.allow_try_trait.clone(),
); );
let try_span = self.sess.source_map().end_point(span); let try_span = self.tcx.sess.source_map().end_point(span);
let try_span = self.mark_span_with_reason( let try_span = self.mark_span_with_reason(
DesugaringKind::QuestionMark, DesugaringKind::QuestionMark,
try_span, try_span,

View file

@ -58,7 +58,6 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
let mut lctx = LoweringContext { let mut lctx = LoweringContext {
// Pseudo-globals. // Pseudo-globals.
tcx: self.tcx, tcx: self.tcx,
sess: &self.tcx.sess,
resolver: self.resolver, resolver: self.resolver,
arena: self.tcx.hir_arena, arena: self.tcx.hir_arena,
@ -1268,7 +1267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn error_on_invalid_abi(&self, abi: StrLit) { fn error_on_invalid_abi(&self, abi: StrLit) {
struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol) struct_span_err!(self.tcx.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
.span_label(abi.span, "invalid ABI") .span_label(abi.span, "invalid ABI")
.help(&format!("valid ABIs: {}", abi::all_names().join(", "))) .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
.emit(); .emit();

View file

@ -49,7 +49,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{struct_span_err, Applicability}; use rustc_errors::{struct_span_err, Applicability, Handler};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
@ -58,7 +58,6 @@ use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DesugaringKind; use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -83,7 +82,6 @@ mod path;
struct LoweringContext<'a, 'hir> { struct LoweringContext<'a, 'hir> {
tcx: TyCtxt<'hir>, tcx: TyCtxt<'hir>,
sess: &'hir Session,
resolver: &'a mut ResolverAstLowering, resolver: &'a mut ResolverAstLowering,
/// Used to allocate HIR nodes. /// Used to allocate HIR nodes.
@ -681,8 +679,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.resolver.get_import_res(id).present_items() self.resolver.get_import_res(id).present_items()
} }
fn diagnostic(&self) -> &rustc_errors::Handler { fn diagnostic(&self) -> &Handler {
self.sess.diagnostic() self.tcx.sess.diagnostic()
} }
/// Reuses the span but adds information like the kind of the desugaring and features that are /// Reuses the span but adds information like the kind of the desugaring and features that are
@ -694,14 +692,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
allow_internal_unstable: Option<Lrc<[Symbol]>>, allow_internal_unstable: Option<Lrc<[Symbol]>>,
) -> Span { ) -> Span {
self.tcx.with_stable_hashing_context(|hcx| { self.tcx.with_stable_hashing_context(|hcx| {
span.mark_with_reason(allow_internal_unstable, reason, self.sess.edition(), hcx) span.mark_with_reason(allow_internal_unstable, reason, self.tcx.sess.edition(), hcx)
}) })
} }
/// Intercept all spans entering HIR. /// Intercept all spans entering HIR.
/// Mark a span as relative to the current owning item. /// Mark a span as relative to the current owning item.
fn lower_span(&self, span: Span) -> Span { fn lower_span(&self, span: Span) -> Span {
if self.sess.opts.debugging_opts.incremental_relative_spans { if self.tcx.sess.opts.debugging_opts.incremental_relative_spans {
span.with_parent(Some(self.current_hir_id_owner)) span.with_parent(Some(self.current_hir_id_owner))
} else { } else {
// Do not make spans relative when not using incremental compilation. // Do not make spans relative when not using incremental compilation.
@ -1048,7 +1046,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) { fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
let mut err = self.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
data.span, data.span,
"parenthesized generic arguments cannot be used in associated type constraints", "parenthesized generic arguments cannot be used in associated type constraints",
); );
@ -1093,7 +1091,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)), ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
ast::GenericArg::Type(ty) => { ast::GenericArg::Type(ty) => {
match ty.kind { match ty.kind {
TyKind::Infer if self.sess.features_untracked().generic_arg_infer => { TyKind::Infer if self.tcx.features().generic_arg_infer => {
return GenericArg::Infer(hir::InferArg { return GenericArg::Infer(hir::InferArg {
hir_id: self.lower_node_id(ty.id), hir_id: self.lower_node_id(ty.id),
span: self.lower_span(ty.span), span: self.lower_span(ty.span),
@ -1190,7 +1188,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else { } else {
self.next_node_id() self.next_node_id()
}; };
let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
}); });
let lifetime = self.lower_lifetime(&region); let lifetime = self.lower_lifetime(&region);
@ -1294,7 +1292,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
ImplTraitContext::Disallowed(position) => { ImplTraitContext::Disallowed(position) => {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.sess, self.tcx.sess,
t.span, t.span,
E0562, E0562,
"`impl Trait` only allowed in function and inherent method return types, not in {}", "`impl Trait` only allowed in function and inherent method return types, not in {}",
@ -1307,7 +1305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"), TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
TyKind::CVarArgs => { TyKind::CVarArgs => {
self.sess.delay_span_bug( self.tcx.sess.delay_span_bug(
t.span, t.span,
"`TyKind::CVarArgs` should have been handled elsewhere", "`TyKind::CVarArgs` should have been handled elsewhere",
); );
@ -1912,7 +1910,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir_id, hir_id,
name, name,
span: self.lower_span(param.span()), span: self.lower_span(param.span()),
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle), pure_wrt_drop: self.tcx.sess.contains_name(&param.attrs, sym::may_dangle),
kind, kind,
colon_span: param.colon_span.map(|s| self.lower_span(s)), colon_span: param.colon_span.map(|s| self.lower_span(s)),
} }
@ -2054,11 +2052,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen { fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
match c.value.kind { match c.value.kind {
ExprKind::Underscore => { ExprKind::Underscore => {
if self.sess.features_untracked().generic_arg_infer { if self.tcx.features().generic_arg_infer {
hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span) hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
} else { } else {
feature_err( feature_err(
&self.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::generic_arg_infer, sym::generic_arg_infer,
c.value.span, c.value.span,
"using `_` for array lengths is unstable", "using `_` for array lengths is unstable",

View file

@ -133,7 +133,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// We should've returned in the for loop above. // We should've returned in the for loop above.
self.sess.diagnostic().span_bug( self.diagnostic().span_bug(
p.span, p.span,
&format!( &format!(
"lower_qpath: no final extension segment in {}..{}", "lower_qpath: no final extension segment in {}..{}",
@ -193,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
ParenthesizedGenericArgs::Err => { ParenthesizedGenericArgs::Err => {
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); let mut err = struct_span_err!(self.tcx.sess, data.span, E0214, "{}", msg);
err.span_label(data.span, "only `Fn` traits may use parentheses"); err.span_label(data.span, "only `Fn` traits may use parentheses");
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
if !data.inputs.is_empty() { if !data.inputs.is_empty() {