summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/late
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
commit837b550238aa671a591ccf282dddeab29cadb206 (patch)
tree914b6b8862bace72bd3245ca184d374b08d8a672 /compiler/rustc_resolve/src/late
parentAdding debian version 1.70.0+dfsg2-1. (diff)
downloadrustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz
rustc-837b550238aa671a591ccf282dddeab29cadb206.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_resolve/src/late')
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs278
1 files changed, 92 insertions, 186 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 37fbfad2d..df6582580 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1,7 +1,7 @@
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
-use crate::path_names_to_string;
+use crate::{errors, path_names_to_string};
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
@@ -22,19 +22,20 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_session::lint;
-use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::Span;
use std::iter;
use std::ops::Deref;
use thin_vec::ThinVec;
+use super::NoConstantGenericsReason;
+
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
@@ -91,7 +92,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str
/// Description of an elided lifetime.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub(super) struct MissingLifetime {
- /// Used to overwrite the resolution with the suggestion, to avoid cascasing errors.
+ /// Used to overwrite the resolution with the suggestion, to avoid cascading errors.
pub id: NodeId,
/// Where to suggest adding the lifetime.
pub span: Span,
@@ -196,8 +197,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.sess
.source_map()
.span_to_snippet(span)
- .map(|snippet| snippet.ends_with(')'))
- .unwrap_or(false)
+ .is_ok_and(|snippet| snippet.ends_with(')'))
}
Res::Def(
DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
@@ -315,8 +315,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
debug!(?res, ?source);
let base_error = self.make_base_error(path, span, source, res);
let code = source.error_code(res.is_some());
- let mut err =
- self.r.tcx.sess.struct_span_err_with_code(base_error.span, &base_error.msg, code);
+ let mut err = self.r.tcx.sess.struct_span_err_with_code(
+ base_error.span,
+ base_error.msg.clone(),
+ code,
+ );
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
@@ -332,7 +335,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if self.suggest_pattern_match_with_let(&mut err, source, span) {
// Fallback label.
- err.span_label(base_error.span, &base_error.fallback_label);
+ err.span_label(base_error.span, base_error.fallback_label);
return (err, Vec::new());
}
@@ -350,18 +353,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
return (err, candidates);
}
- if !self.type_ascription_suggestion(&mut err, base_error.span) {
- let mut fallback =
- self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
+ let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
- // if we have suggested using pattern matching, then don't add needless suggestions
- // for typos.
- fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
+ // if we have suggested using pattern matching, then don't add needless suggestions
+ // for typos.
+ fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
- if fallback {
- // Fallback label.
- err.span_label(base_error.span, &base_error.fallback_label);
- }
+ if fallback {
+ // Fallback label.
+ err.span_label(base_error.span, base_error.fallback_label);
}
self.err_code_special_cases(&mut err, source, path, span);
@@ -408,7 +408,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
let Some(path_last_segment) = path.last() else { return };
let item_str = path_last_segment.ident;
- // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
+ // Emit help message for fake-self from other languages (e.g., `this` in JavaScript).
if ["this", "my"].contains(&item_str.as_str()) {
err.span_suggestion_short(
span,
@@ -494,24 +494,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.filter(|(_, enum_ty_path)| !enum_ty_path.starts_with("std::prelude::"))
.collect();
if !enum_candidates.is_empty() {
- if let (PathSource::Type, Some(span)) =
- (source, self.diagnostic_metadata.current_type_ascription.last())
- {
- if self
- .r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow()
- .contains(span)
- {
- // Already reported this issue on the lhs of the type ascription.
- err.downgrade_to_delayed_bug();
- return (true, candidates);
- }
- }
-
enum_candidates.sort();
// Contextualize for E0412 "cannot find type", but don't belabor the point
@@ -530,7 +512,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestions(
span,
- &msg,
+ msg,
enum_candidates.into_iter().map(|(_variant_path, enum_ty_path)| enum_ty_path),
Applicability::MachineApplicable,
);
@@ -577,7 +559,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
| AssocSuggestion::AssocType => {
err.span_suggestion(
span,
- &format!("you might have meant to {}", candidate.action()),
+ format!("you might have meant to {}", candidate.action()),
format!("Self::{path_str}"),
Applicability::MachineApplicable,
);
@@ -598,7 +580,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestion(
call_span,
- &format!("try calling `{ident}` as a method"),
+ format!("try calling `{ident}` as a method"),
format!("self.{path_str}({args_snippet})"),
Applicability::MachineApplicable,
);
@@ -623,14 +605,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
// Try to find in last block rib
- if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
+ if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind {
for (ident, &res) in &rib.bindings {
if let Res::Local(_) = res && path.len() == 1 &&
ident.span.eq_ctxt(path[0].ident.span) &&
ident.name == path[0].ident.name {
err.span_help(
ident.span,
- &format!("the binding `{}` is available in a different scope in the same function", path_str),
+ format!("the binding `{}` is available in a different scope in the same function", path_str),
);
return (true, candidates);
}
@@ -739,7 +721,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
&& res
.opt_def_id()
- .map_or(false, |id| id.is_local() || is_in_same_file(span, sugg_span))
+ .is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span))
{
err.span_label(
sugg_span,
@@ -873,7 +855,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
// The current function has a `self` parameter, but we were unable to resolve
// a reference to `self`. This can only happen if the `self` identifier we
// are resolving came from a different hygiene context.
- if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
+ if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
} else {
let doesnt = if is_assoc_fn {
@@ -911,7 +893,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if let Some(ident) = fn_kind.ident() {
err.span_label(
ident.span,
- &format!("this function {} have a `self` parameter", doesnt),
+ format!("this function {} have a `self` parameter", doesnt),
);
}
}
@@ -1087,7 +1069,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if ident.span == span {
err.span_suggestion_verbose(
*where_span,
- &format!("constrain the associated type to `{}`", ident),
+ format!("constrain the associated type to `{}`", ident),
format!(
"{}: {}<{} = {}>",
self.r
@@ -1288,7 +1270,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
let span = find_span(&source, err);
- err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+ err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
let (tail, descr, applicability, old_fields) = match source {
PathSource::Pat => ("", "pattern", Applicability::MachineApplicable, None),
@@ -1332,7 +1314,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
};
err.span_suggestion(
span,
- &format!("use struct {} syntax instead", descr),
+ format!("use struct {} syntax instead", descr),
format!("{path_str} {{{pad}{fields}{pad}}}"),
applicability,
);
@@ -1393,26 +1375,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
Res::Def(DefKind::Enum, def_id),
PathSource::TupleStruct(..) | PathSource::Expr(..),
) => {
- if self
- .diagnostic_metadata
- .current_type_ascription
- .last()
- .map(|sp| {
- self.r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow()
- .contains(&sp)
- })
- .unwrap_or(false)
- {
- err.downgrade_to_delayed_bug();
- // We already suggested changing `:` into `::` during parsing.
- return false;
- }
-
self.suggest_using_enum_variant(err, source, def_id, span);
}
(Res::Def(DefKind::Struct, def_id), source) if ns == ValueNS => {
@@ -1494,7 +1456,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if non_visible_spans.len() > 0 {
if let Some(fields) = self.r.field_visibility_spans.get(&def_id) {
err.multipart_suggestion_verbose(
- &format!(
+ format!(
"consider making the field{} publicly accessible",
pluralize!(fields.len())
),
@@ -1524,7 +1486,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let span = find_span(&source, err);
err.span_label(
self.r.def_span(def_id),
- &format!("`{path_str}` defined here"),
+ format!("`{path_str}` defined here"),
);
err.span_suggestion(
span,
@@ -1538,7 +1500,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => {
let def_id = self.r.tcx.parent(ctor_def_id);
- err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+ err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
let fields = self.r.field_def_ids(def_id).map_or_else(
|| "/* fields */".to_string(),
|field_ids| vec!["_"; field_ids.len()].join(", "),
@@ -1669,7 +1631,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.tcx
.fn_arg_names(def_id)
.first()
- .map_or(false, |ident| ident.name == kw::SelfLower),
+ .is_some_and(|ident| ident.name == kw::SelfLower),
};
if has_self {
return Some(AssocSuggestion::MethodWithSelf { called });
@@ -1728,7 +1690,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
// Items in scope
- if let RibKind::ModuleRibKind(module) = rib.kind {
+ if let RibKind::Module(module) = rib.kind {
// Items from this module
self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
@@ -1817,80 +1779,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
})
}
- /// Only used in a specific case of type ascription suggestions
- fn get_colon_suggestion_span(&self, start: Span) -> Span {
- let sm = self.r.tcx.sess.source_map();
- start.to(sm.next_point(start))
- }
-
- fn type_ascription_suggestion(&self, err: &mut Diagnostic, base_span: Span) -> bool {
- let sm = self.r.tcx.sess.source_map();
- let base_snippet = sm.span_to_snippet(base_span);
- if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() {
- if let Ok(snippet) = sm.span_to_snippet(sp) {
- let len = snippet.trim_end().len() as u32;
- if snippet.trim() == ":" {
- let colon_sp =
- sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len));
- let mut show_label = true;
- if sm.is_multiline(sp) {
- err.span_suggestion_short(
- colon_sp,
- "maybe you meant to write `;` here",
- ";",
- Applicability::MaybeIncorrect,
- );
- } else {
- let after_colon_sp =
- self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
- if snippet.len() == 1 {
- // `foo:bar`
- err.span_suggestion(
- colon_sp,
- "maybe you meant to write a path separator here",
- "::",
- Applicability::MaybeIncorrect,
- );
- show_label = false;
- if !self
- .r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow_mut()
- .insert(colon_sp)
- {
- err.downgrade_to_delayed_bug();
- }
- }
- if let Ok(base_snippet) = base_snippet {
- // Try to find an assignment
- let eq_span = sm.span_look_ahead(after_colon_sp, Some("="), Some(50));
- if let Ok(ref snippet) = sm.span_to_snippet(eq_span) && snippet == "=" {
- err.span_suggestion(
- base_span,
- "maybe you meant to write an assignment here",
- format!("let {}", base_snippet),
- Applicability::MaybeIncorrect,
- );
- show_label = false;
- }
- }
- }
- if show_label {
- err.span_label(
- base_span,
- "expecting a type here because of type ascription",
- );
- }
- return show_label;
- }
- }
- }
- false
- }
-
// try to give a suggestion for this pattern: `name = blah`, which is common in other languages
// suggest `let name = blah` to introduce a new binding
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
@@ -2014,7 +1902,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestions(
span,
- &msg,
+ msg,
suggestable_variants,
Applicability::MaybeIncorrect,
);
@@ -2022,17 +1910,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
// If the enum has no tuple variants..
if non_suggestable_variant_count == variants.len() {
- err.help(&format!("the enum has no tuple variants {}", source_msg));
+ err.help(format!("the enum has no tuple variants {}", source_msg));
}
// If there are also non-tuple variants..
if non_suggestable_variant_count == 1 {
- err.help(&format!(
+ err.help(format!(
"you might have meant {} the enum's non-tuple variant",
source_msg
));
} else if non_suggestable_variant_count >= 1 {
- err.help(&format!(
+ err.help(format!(
"you might have meant {} one of the enum's non-tuple variants",
source_msg
));
@@ -2042,10 +1930,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let def_id = self.r.tcx.parent(ctor_def_id);
match kind {
CtorKind::Const => false,
- CtorKind::Fn => !self
- .r
- .field_def_ids(def_id)
- .map_or(false, |field_ids| field_ids.is_empty()),
+ CtorKind::Fn => {
+ !self.r.field_def_ids(def_id).is_some_and(|field_ids| field_ids.is_empty())
+ }
}
};
@@ -2282,7 +2169,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
lint::builtin::SINGLE_USE_LIFETIMES,
param.id,
param.ident.span,
- &format!("lifetime parameter `{}` only used once", param.ident),
+ format!("lifetime parameter `{}` only used once", param.ident),
lint::BuiltinLintDiagnostics::SingleUseLifetime {
param_span: param.ident.span,
use_span: Some((use_span, elidable)),
@@ -2301,7 +2188,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
lint::builtin::UNUSED_LIFETIMES,
param.id,
param.ident.span,
- &format!("lifetime parameter `{}` never used", param.ident),
+ format!("lifetime parameter `{}` never used", param.ident),
lint::BuiltinLintDiagnostics::SingleUseLifetime {
param_span: param.ident.span,
use_span: None,
@@ -2367,7 +2254,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
suggest_note = false; // Avoid displaying the same help multiple times.
err.span_label(
span,
- &format!(
+ format!(
"lifetime `{}` is missing in item created through this procedural macro",
name,
),
@@ -2428,37 +2315,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
}
- pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
- struct_span_err!(
- self.r.tcx.sess,
- lifetime_ref.ident.span,
- E0771,
- "use of non-static lifetime `{}` in const generic",
- lifetime_ref.ident
- )
- .note(
- "for more information, see issue #74052 \
- <https://github.com/rust-lang/rust/issues/74052>",
- )
- .emit();
+ pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInTyOfConstParam {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
+ })
+ .emit();
}
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
- pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+ pub(crate) fn emit_forbidden_non_static_lifetime_error(
&self,
+ cause: NoConstantGenericsReason,
lifetime_ref: &ast::Lifetime,
) {
- let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
- if !feature_active {
- feature_err(
- &self.r.tcx.sess.parse_sess,
- sym::generic_const_exprs,
- lifetime_ref.ident.span,
- "a non-static lifetime is not allowed in a `const`",
- )
- .emit();
+ match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInEnumDiscriminant {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
+ })
+ .emit();
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ assert!(!self.r.tcx.features().generic_const_exprs);
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInNonTrivialAnonConst {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
+ help: self
+ .r
+ .tcx
+ .sess
+ .is_nightly_build()
+ .then_some(errors::ParamInNonTrivialAnonConstHelp),
+ })
+ .emit();
+ }
}
}
@@ -2573,13 +2479,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
)];
}
} else if num_params == 1 {
- err.help(&format!(
+ err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say which {} it is borrowed from",
m
));
} else {
- err.help(&format!(
+ err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say whether it is borrowed from {}",
m
@@ -2648,7 +2554,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
1 => {
err.multipart_suggestion_verbose(
- &format!("consider using the `{}` lifetime", existing_name),
+ format!("consider using the `{}` lifetime", existing_name),
spans_suggs,
Applicability::MaybeIncorrect,
);
@@ -2699,7 +2605,7 @@ pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident
let shadower = shadower.span;
let mut err = sess.struct_span_warn(
shadower,
- &format!("label name `{}` shadows a label name that is already in scope", name),
+ format!("label name `{}` shadows a label name that is already in scope", name),
);
err.span_label(orig, "first declared here");
err.span_label(shadower, format!("label `{}` already in scope", name));