summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs649
1 files changed, 249 insertions, 400 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 5d868ebec..e392df6c5 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -25,7 +25,9 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span, SyntaxContext};
+use thin_vec::ThinVec;
+use crate::errors as errs;
use crate::imports::{Import, ImportKind, ImportResolver};
use crate::late::{PatternSource, Rib};
use crate::path_names_to_string;
@@ -58,16 +60,32 @@ pub(crate) enum SuggestionTarget {
#[derive(Debug)]
pub(crate) struct TypoSuggestion {
pub candidate: Symbol,
+ /// The source location where the name is defined; None if the name is not defined
+ /// in source e.g. primitives
+ pub span: Option<Span>,
pub res: Res,
pub target: SuggestionTarget,
}
impl TypoSuggestion {
- pub(crate) fn typo_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
- Self { candidate, res, target: SuggestionTarget::SimilarlyNamed }
+ pub(crate) fn typo_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
+ Self {
+ candidate: ident.name,
+ span: Some(ident.span),
+ res,
+ target: SuggestionTarget::SimilarlyNamed,
+ }
+ }
+ pub(crate) fn typo_from_name(candidate: Symbol, res: Res) -> TypoSuggestion {
+ Self { candidate, span: None, res, target: SuggestionTarget::SimilarlyNamed }
}
- pub(crate) fn single_item_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
- Self { candidate, res, target: SuggestionTarget::SingleItem }
+ pub(crate) fn single_item_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
+ Self {
+ candidate: ident.name,
+ span: Some(ident.span),
+ res,
+ target: SuggestionTarget::SingleItem,
+ }
}
}
@@ -174,12 +192,12 @@ impl<'a> Resolver<'a> {
ModuleKind::Block => "block",
};
- let old_noun = match old_binding.is_import() {
+ let old_noun = match old_binding.is_import_user_facing() {
true => "import",
false => "definition",
};
- let new_participle = match new_binding.is_import() {
+ let new_participle = match new_binding.is_import_user_facing() {
true => "imported",
false => "defined",
};
@@ -210,7 +228,7 @@ impl<'a> Resolver<'a> {
true => struct_span_err!(self.session, span, E0254, "{}", msg),
false => struct_span_err!(self.session, span, E0260, "{}", msg),
},
- _ => match (old_binding.is_import(), new_binding.is_import()) {
+ _ => match (old_binding.is_import_user_facing(), new_binding.is_import_user_facing()) {
(false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
(true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
_ => struct_span_err!(self.session, span, E0255, "{}", msg),
@@ -225,21 +243,27 @@ impl<'a> Resolver<'a> {
));
err.span_label(span, format!("`{}` re{} here", name, new_participle));
- err.span_label(
- self.session.source_map().guess_head_span(old_binding.span),
- format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
- );
+ if !old_binding.span.is_dummy() && old_binding.span != span {
+ err.span_label(
+ self.session.source_map().guess_head_span(old_binding.span),
+ format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
+ );
+ }
// See https://github.com/rust-lang/rust/issues/32354
use NameBindingKind::Import;
+ let can_suggest = |binding: &NameBinding<'_>, import: &self::Import<'_>| {
+ !binding.span.is_dummy()
+ && !matches!(import.kind, ImportKind::MacroUse | ImportKind::MacroExport)
+ };
let import = match (&new_binding.kind, &old_binding.kind) {
// If there are two imports where one or both have attributes then prefer removing the
// import without attributes.
(Import { import: new, .. }, Import { import: old, .. })
if {
- !new_binding.span.is_dummy()
- && !old_binding.span.is_dummy()
- && (new.has_attributes || old.has_attributes)
+ (new.has_attributes || old.has_attributes)
+ && can_suggest(old_binding, old)
+ && can_suggest(new_binding, new)
} =>
{
if old.has_attributes {
@@ -249,10 +273,10 @@ impl<'a> Resolver<'a> {
}
}
// Otherwise prioritize the new binding.
- (Import { import, .. }, other) if !new_binding.span.is_dummy() => {
+ (Import { import, .. }, other) if can_suggest(new_binding, import) => {
Some((import, new_binding.span, other.is_import()))
}
- (other, Import { import, .. }) if !old_binding.span.is_dummy() => {
+ (other, Import { import, .. }) if can_suggest(old_binding, import) => {
Some((import, old_binding.span, other.is_import()))
}
_ => None,
@@ -337,7 +361,7 @@ impl<'a> Resolver<'a> {
}
}
}
- ImportKind::ExternCrate { source, target } => {
+ ImportKind::ExternCrate { source, target, .. } => {
suggestion = Some(format!(
"extern crate {} as {};",
source.unwrap_or(target.name),
@@ -490,7 +514,7 @@ impl<'a> Resolver<'a> {
if let Some(binding) = resolution.borrow().binding {
let res = binding.res();
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
- names.push(TypoSuggestion::typo_from_res(key.ident.name, res));
+ names.push(TypoSuggestion::typo_from_ident(key.ident, res));
}
}
}
@@ -575,78 +599,41 @@ impl<'a> Resolver<'a> {
err
}
- ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0403,
- "the name `{}` is already used for a generic \
- parameter in this item's generic parameters",
- name,
- );
- err.span_label(span, "already used");
- err.span_label(first_use_span, format!("first use of `{}`", name));
- err
- }
+ ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self
+ .session
+ .create_err(errs::NameAlreadyUsedInParameterList { span, first_use_span, name }),
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::MethodNotMemberOfTrait {
span,
- E0407,
- "method `{}` is not a member of trait `{}`",
method,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- method.span,
- "there is an associated function with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedFnWithSimilarNameExists {
+ span: method.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::TypeNotMemberOfTrait {
span,
- E0437,
- "type `{}` is not a member of trait `{}`",
type_,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- type_.span,
- "there is an associated type with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedTypeWithSimilarNameExists {
+ span: type_.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::ConstNotMemberOfTrait {
span,
- E0438,
- "const `{}` is not a member of trait `{}`",
const_,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- const_.span,
- "there is an associated constant with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedConstWithSimilarNameExists {
+ span: const_.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => {
let BindingError { name, target, origin, could_be_path } = binding_error;
@@ -708,128 +695,78 @@ impl<'a> Resolver<'a> {
err
}
ResolutionError::VariableBoundWithDifferentMode(variable_name, first_binding_span) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0409,
- "variable `{}` is bound inconsistently across alternatives separated by `|`",
- variable_name
- );
- err.span_label(span, "bound in different ways");
- err.span_label(first_binding_span, "first binding");
- err
- }
- ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0415,
- "identifier `{}` is bound more than once in this parameter list",
- identifier
- );
- err.span_label(span, "used as parameter more than once");
- err
- }
- ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::VariableBoundWithDifferentMode {
span,
- E0416,
- "identifier `{}` is bound more than once in the same pattern",
- identifier
- );
- err.span_label(span, "used in a pattern more than once");
- err
- }
+ first_binding_span,
+ variable_name,
+ })
+ }
+ ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => self
+ .session
+ .create_err(errs::IdentifierBoundMoreThanOnceInParameterList { span, identifier }),
+ ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => self
+ .session
+ .create_err(errs::IdentifierBoundMoreThanOnceInSamePattern { span, identifier }),
ResolutionError::UndeclaredLabel { name, suggestion } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0426,
- "use of undeclared label `{}`",
- name
- );
-
- err.span_label(span, format!("undeclared label `{}`", name));
-
- match suggestion {
+ let ((sub_reachable, sub_reachable_suggestion), sub_unreachable) = match suggestion
+ {
// A reachable label with a similar name exists.
- Some((ident, true)) => {
- err.span_label(ident.span, "a label with a similar name is reachable");
- err.span_suggestion(
- span,
- "try using similarly named label",
- ident.name,
- Applicability::MaybeIncorrect,
- );
- }
+ Some((ident, true)) => (
+ (
+ Some(errs::LabelWithSimilarNameReachable(ident.span)),
+ Some(errs::TryUsingSimilarlyNamedLabel {
+ span,
+ ident_name: ident.name,
+ }),
+ ),
+ None,
+ ),
// An unreachable label with a similar name exists.
- Some((ident, false)) => {
- err.span_label(
- ident.span,
- "a label with a similar name exists but is unreachable",
- );
- }
+ Some((ident, false)) => (
+ (None, None),
+ Some(errs::UnreachableLabelWithSimilarNameExists {
+ ident_span: ident.span,
+ }),
+ ),
// No similarly-named labels exist.
- None => (),
- }
-
- err
+ None => ((None, None), None),
+ };
+ self.session.create_err(errs::UndeclaredLabel {
+ span,
+ name,
+ sub_reachable,
+ sub_reachable_suggestion,
+ sub_unreachable,
+ })
}
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0429,
- "{}",
- "`self` imports are only allowed within a { } list"
- );
-
// None of the suggestions below would help with a case like `use self`.
- if !root {
+ let (suggestion, mpart_suggestion) = if root {
+ (None, None)
+ } else {
// use foo::bar::self -> foo::bar
// use foo::bar::self as abc -> foo::bar as abc
- err.span_suggestion(
- span,
- "consider importing the module directly",
- "",
- Applicability::MachineApplicable,
- );
+ let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
// use foo::bar::self -> foo::bar::{self}
// use foo::bar::self as abc -> foo::bar::{self as abc}
- let braces = vec![
- (span_with_rename.shrink_to_lo(), "{".to_string()),
- (span_with_rename.shrink_to_hi(), "}".to_string()),
- ];
- err.multipart_suggestion(
- "alternatively, use the multi-path `use` syntax to import `self`",
- braces,
- Applicability::MachineApplicable,
- );
- }
- err
+ let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
+ multipart_start: span_with_rename.shrink_to_lo(),
+ multipart_end: span_with_rename.shrink_to_hi(),
+ };
+ (Some(suggestion), Some(mpart_suggestion))
+ };
+ self.session.create_err(errs::SelfImportsOnlyAllowedWithin {
+ span,
+ suggestion,
+ mpart_suggestion,
+ })
}
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0430,
- "`self` import can only appear once in an import list"
- );
- err.span_label(span, "can only appear once in an import list");
- err
+ self.session.create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span })
}
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0431,
- "`self` import can only appear in an import list with \
- a non-empty prefix"
- );
- err.span_label(span, "can only appear in an import list with a non-empty prefix");
- err
+ self.session.create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
}
ResolutionError::FailedToResolve { label, suggestion } => {
let mut err =
@@ -847,23 +784,9 @@ impl<'a> Resolver<'a> {
err
}
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0434,
- "{}",
- "can't capture dynamic environment in a fn item"
- );
- err.help("use the `|| { ... }` closure form instead");
- err
+ self.session.create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
}
- ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0435,
- "attempt to use a non-constant value in a constant"
- );
+ ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
// let foo =...
// ^^^ given this Span
// ------- get this Span to have an applicable suggestion
@@ -877,23 +800,34 @@ impl<'a> Resolver<'a> {
.source_map()
.span_extend_to_prev_str(ident.span, current, true, false);
- match sp {
+ let ((with, with_label), without) = match sp {
Some(sp) if !self.session.source_map().is_multiline(sp) => {
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
- err.span_suggestion(
- sp,
- &format!("consider using `{}` instead of `{}`", sugg, current),
- format!("{} {}", sugg, ident),
- Applicability::MaybeIncorrect,
- );
- err.span_label(span, "non-constant value");
- }
- _ => {
- err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
+ (
+ (Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
+ span: sp,
+ ident,
+ suggestion,
+ current,
+ }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
+ None,
+ )
}
- }
+ _ => (
+ (None, None),
+ Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion {
+ ident_span: ident.span,
+ suggestion,
+ }),
+ ),
+ };
- err
+ self.session.create_err(errs::AttemptToUseNonConstantValueInConstant {
+ span,
+ with,
+ with_label,
+ without,
+ })
}
ResolutionError::BindingShadowsSomethingUnacceptable {
shadowing_binding,
@@ -902,135 +836,80 @@ impl<'a> Resolver<'a> {
article,
shadowed_binding,
shadowed_binding_span,
- } => {
- let shadowed_binding_descr = shadowed_binding.descr();
- let mut err = struct_span_err!(
- self.session,
- span,
- E0530,
- "{}s cannot shadow {}s",
- shadowing_binding.descr(),
- shadowed_binding_descr,
- );
- err.span_label(
- span,
- format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
- );
- match (shadowing_binding, shadowed_binding) {
+ } => self.session.create_err(errs::BindingShadowsSomethingUnacceptable {
+ span,
+ shadowing_binding,
+ shadowed_binding,
+ article,
+ sub_suggestion: match (shadowing_binding, shadowed_binding) {
(
PatternSource::Match,
Res::Def(DefKind::Ctor(CtorOf::Variant | CtorOf::Struct, CtorKind::Fn), _),
- ) => {
- err.span_suggestion(
- span,
- "try specify the pattern arguments",
- format!("{}(..)", name),
- Applicability::Unspecified,
- );
- }
- _ => (),
- }
- let msg =
- format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
- err.span_label(shadowed_binding_span, msg);
- err
- }
+ ) => Some(errs::BindingShadowsSomethingUnacceptableSuggestion { span, name }),
+ _ => None,
+ },
+ shadowed_binding_span,
+ participle,
+ name,
+ }),
ResolutionError::ForwardDeclaredGenericParam => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0128,
- "generic parameters with a default cannot use \
- forward declared identifiers"
- );
- err.span_label(span, "defaulted generic parameters cannot be forward declared");
- err
+ self.session.create_err(errs::ForwardDeclaredGenericParam { span })
}
ResolutionError::ParamInTyOfConstParam(name) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0770,
- "the type of const parameters must not depend on other generic parameters"
- );
- err.span_label(
- span,
- format!("the type must not depend on the parameter `{}`", name),
- );
- err
+ self.session.create_err(errs::ParamInTyOfConstParam { span, name })
}
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
- let mut err = self.session.struct_span_err(
+ self.session.create_err(errs::ParamInNonTrivialAnonConst {
span,
- "generic parameters may not be used in const operations",
- );
- err.span_label(span, &format!("cannot perform const operation using `{}`", name));
-
- if is_type {
- err.note("type parameters may not be used in const expressions");
- } else {
- err.help(&format!(
- "const parameters may only be used as standalone arguments, i.e. `{}`",
- name
- ));
- }
-
- if self.session.is_nightly_build() {
- err.help(
- "use `#![feature(generic_const_exprs)]` to allow generic const expressions",
- );
- }
-
- err
+ name,
+ sub_is_type: if is_type {
+ errs::ParamInNonTrivialAnonConstIsType::AType
+ } else {
+ errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
+ },
+ help: self
+ .session
+ .is_nightly_build()
+ .then_some(errs::ParamInNonTrivialAnonConstHelp),
+ })
}
ResolutionError::SelfInGenericParamDefault => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0735,
- "generic parameters cannot use `Self` in their defaults"
- );
- err.span_label(span, "`Self` in generic parameter default");
- err
+ self.session.create_err(errs::SelfInGenericParamDefault { span })
}
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
- let mut err = struct_span_err!(
- self.session,
+ let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
+ match suggestion {
+ // A reachable label with a similar name exists.
+ Some((ident, true)) => (
+ (
+ Some(errs::UnreachableLabelSubLabel { ident_span: ident.span }),
+ Some(errs::UnreachableLabelSubSuggestion {
+ span,
+ // intentionally taking 'ident.name' instead of 'ident' itself, as this
+ // could be used in suggestion context
+ ident_name: ident.name,
+ }),
+ ),
+ None,
+ ),
+ // An unreachable label with a similar name exists.
+ Some((ident, false)) => (
+ (None, None),
+ Some(errs::UnreachableLabelSubLabelUnreachable {
+ ident_span: ident.span,
+ }),
+ ),
+ // No similarly-named labels exist.
+ None => ((None, None), None),
+ };
+ self.session.create_err(errs::UnreachableLabel {
span,
- E0767,
- "use of unreachable label `{}`",
name,
- );
-
- err.span_label(definition_span, "unreachable label defined here");
- err.span_label(span, format!("unreachable label `{}`", name));
- err.note(
- "labels are unreachable through functions, closures, async blocks and modules",
- );
-
- match suggestion {
- // A reachable label with a similar name exists.
- Some((ident, true)) => {
- err.span_label(ident.span, "a label with a similar name is reachable");
- err.span_suggestion(
- span,
- "try using similarly named label",
- ident.name,
- Applicability::MaybeIncorrect,
- );
- }
- // An unreachable label with a similar name exists.
- Some((ident, false)) => {
- err.span_label(
- ident.span,
- "a label with a similar name exists but is also unreachable",
- );
- }
- // No similarly-named labels exist.
- None => (),
- }
-
- err
+ definition_span,
+ sub_suggestion,
+ sub_suggestion_label,
+ sub_unreachable_label,
+ })
}
ResolutionError::TraitImplMismatch {
name,
@@ -1051,25 +930,10 @@ impl<'a> Resolver<'a> {
err.span_label(trait_item_span, "item in trait");
err
}
- ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0201,
- "duplicate definitions with name `{}`:",
- name,
- );
- err.span_label(old_span, "previous definition here");
- err.span_label(trait_item_span, "item in trait");
- err.span_label(span, "duplicate definition");
- err
- }
- ResolutionError::InvalidAsmSym => {
- let mut err = self.session.struct_span_err(span, "invalid `sym` operand");
- err.span_label(span, "is a local variable");
- err.help("`sym` operands must refer to either a function or a static");
- err
- }
+ ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self
+ .session
+ .create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }),
+ ResolutionError::InvalidAsmSym => self.session.create_err(errs::InvalidAsmSym { span }),
}
}
@@ -1079,48 +943,27 @@ impl<'a> Resolver<'a> {
) -> ErrorGuaranteed {
match vis_resolution_error {
VisResolutionError::Relative2018(span, path) => {
- let mut err = self.session.struct_span_err(
+ self.session.create_err(errs::Relative2018 {
span,
- "relative paths are not supported in visibilities in 2018 edition or later",
- );
- err.span_suggestion(
- path.span,
- "try",
- format!("crate::{}", pprust::path_to_string(&path)),
- Applicability::MaybeIncorrect,
- );
- err
+ path_span: path.span,
+ // intentionally converting to String, as the text would also be used as
+ // in suggestion context
+ path_str: pprust::path_to_string(&path),
+ })
+ }
+ VisResolutionError::AncestorOnly(span) => {
+ self.session.create_err(errs::AncestorOnly(span))
}
- VisResolutionError::AncestorOnly(span) => struct_span_err!(
- self.session,
- span,
- E0742,
- "visibilities can only be restricted to ancestor modules"
- ),
VisResolutionError::FailedToResolve(span, label, suggestion) => {
self.into_struct_error(span, ResolutionError::FailedToResolve { label, suggestion })
}
VisResolutionError::ExpectedFound(span, path_str, res) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0577,
- "expected module, found {} `{}`",
- res.descr(),
- path_str
- );
- err.span_label(span, "not a module");
- err
+ self.session.create_err(errs::ExpectedFound { span, res, path_str })
}
- VisResolutionError::Indeterminate(span) => struct_span_err!(
- self.session,
- span,
- E0578,
- "cannot determine resolution for the visibility"
- ),
- VisResolutionError::ModuleOnly(span) => {
- self.session.struct_span_err(span, "visibility must resolve to a module")
+ VisResolutionError::Indeterminate(span) => {
+ self.session.create_err(errs::Indeterminate(span))
}
+ VisResolutionError::ModuleOnly(span) => self.session.create_err(errs::ModuleOnly(span)),
}
.emit()
}
@@ -1145,7 +988,7 @@ impl<'a> Resolver<'a> {
.get(&expn_id)
.into_iter()
.flatten()
- .map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
+ .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
);
}
}
@@ -1164,7 +1007,7 @@ impl<'a> Resolver<'a> {
suggestions.extend(
ext.helper_attrs
.iter()
- .map(|name| TypoSuggestion::typo_from_res(*name, res)),
+ .map(|name| TypoSuggestion::typo_from_name(*name, res)),
);
}
}
@@ -1174,8 +1017,8 @@ impl<'a> Resolver<'a> {
if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() {
let res = macro_rules_binding.binding.res();
if filter_fn(res) {
- suggestions.push(TypoSuggestion::typo_from_res(
- macro_rules_binding.ident.name,
+ suggestions.push(TypoSuggestion::typo_from_ident(
+ macro_rules_binding.ident,
res,
))
}
@@ -1193,7 +1036,7 @@ impl<'a> Resolver<'a> {
suggestions.extend(this.macro_use_prelude.iter().filter_map(
|(name, binding)| {
let res = binding.res();
- filter_fn(res).then_some(TypoSuggestion::typo_from_res(*name, res))
+ filter_fn(res).then_some(TypoSuggestion::typo_from_name(*name, res))
},
));
}
@@ -1203,14 +1046,14 @@ impl<'a> Resolver<'a> {
suggestions.extend(
BUILTIN_ATTRIBUTES
.iter()
- .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)),
+ .map(|attr| TypoSuggestion::typo_from_name(attr.name, res)),
);
}
}
Scope::ExternPrelude => {
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
- filter_fn(res).then_some(TypoSuggestion::typo_from_res(ident.name, res))
+ filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
}));
}
Scope::ToolPrelude => {
@@ -1218,7 +1061,7 @@ impl<'a> Resolver<'a> {
suggestions.extend(
this.registered_tools
.iter()
- .map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
+ .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
);
}
Scope::StdLibPrelude => {
@@ -1235,7 +1078,8 @@ impl<'a> Resolver<'a> {
Scope::BuiltinTypes => {
suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| {
let res = Res::PrimTy(*prim_ty);
- filter_fn(res).then_some(TypoSuggestion::typo_from_res(prim_ty.name(), res))
+ filter_fn(res)
+ .then_some(TypoSuggestion::typo_from_name(prim_ty.name(), res))
}))
}
}
@@ -1272,7 +1116,7 @@ impl<'a> Resolver<'a> {
{
let mut candidates = Vec::new();
let mut seen_modules = FxHashSet::default();
- let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), true)];
+ let mut worklist = vec![(start_module, ThinVec::<ast::PathSegment>::new(), true)];
let mut worklist_via_import = vec![];
while let Some((in_module, path_segments, accessible)) = match worklist.pop() {
@@ -1666,7 +1510,7 @@ impl<'a> Resolver<'a> {
let a = if built_in.is_empty() { res.article() } else { "a" };
format!("{a}{built_in} {thing}{from}", thing = res.descr())
} else {
- let introduced = if b.is_import() { "imported" } else { "defined" };
+ let introduced = if b.is_import_user_facing() { "imported" } else { "defined" };
format!("the {thing} {introduced} here", thing = res.descr())
}
}
@@ -1725,10 +1569,10 @@ impl<'a> Resolver<'a> {
/// If the binding refers to a tuple struct constructor with fields,
/// returns the span of its fields.
fn ctor_fields_span(&self, binding: &NameBinding<'_>) -> Option<Span> {
- if let NameBindingKind::Res(
- Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id),
- _,
- ) = binding.kind
+ if let NameBindingKind::Res(Res::Def(
+ DefKind::Ctor(CtorOf::Struct, CtorKind::Fn),
+ ctor_def_id,
+ )) = binding.kind
{
let def_id = self.parent(ctor_def_id);
let fields = self.field_names.get(&def_id)?;
@@ -1772,7 +1616,9 @@ impl<'a> Resolver<'a> {
next_ident = source;
Some(binding)
}
- ImportKind::Glob { .. } | ImportKind::MacroUse => Some(binding),
+ ImportKind::Glob { .. } | ImportKind::MacroUse | ImportKind::MacroExport => {
+ Some(binding)
+ }
ImportKind::ExternCrate { .. } => None,
},
_ => None,
@@ -1994,13 +1840,16 @@ impl<'a> Resolver<'a> {
(format!("use of undeclared type `{}`", ident), suggestion)
} else {
- let suggestion = if ident.name == sym::alloc {
- Some((
+ let mut suggestion = None;
+ if ident.name == sym::alloc {
+ suggestion = Some((
vec![],
String::from("add `extern crate alloc` to use the `alloc` crate"),
Applicability::MaybeIncorrect,
))
- } else {
+ }
+
+ suggestion = suggestion.or_else(|| {
self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map(
|sugg| {
(
@@ -2010,7 +1859,7 @@ impl<'a> Resolver<'a> {
)
},
)
- };
+ });
(format!("use of undeclared crate or module `{}`", ident), suggestion)
}
}