1
Fork 0

resolve: Turn resolve_error into a method on Resolver

Rename it to `report_error` and move into `diagnostics.rs`

Also turn `check_unused` into a method on `Resolver`
This commit is contained in:
Vadim Petrochenkov 2019-08-08 23:32:58 +03:00
parent 6a347f3701
commit 9c86ce76e5
7 changed files with 417 additions and 428 deletions

View file

@ -9,7 +9,7 @@ use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleIm
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
use crate::{ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas, ExternPreludeEntry};
use crate::Namespace::{self, TypeNS, ValueNS, MacroNS};
use crate::{resolve_error, resolve_struct_error, ResolutionError, Determinacy};
use crate::{ResolutionError, Determinacy};
use rustc::bug;
use rustc::hir::def::{self, *};
@ -165,8 +165,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
type_ns_only = true;
if empty_for_self(&module_path) {
resolve_error(
&self.r,
self.r.report_error(
use_tree.span,
ResolutionError::
SelfImportOnlyInImportListWithNonEmptyPrefix
@ -183,9 +182,9 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
} else {
// Disallow `self`
if source.ident.name == kw::SelfLower {
resolve_error(&self.r,
use_tree.span,
ResolutionError::SelfImportsOnlyAllowedWithin);
self.r.report_error(
use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin
);
}
// Disallow `use $crate;`
@ -283,7 +282,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
None
}).collect::<Vec<_>>();
if self_spans.len() > 1 {
let mut e = resolve_struct_error(&self.r,
let mut e = self.r.into_struct_error(
self_spans[0],
ResolutionError::SelfImportCanOnlyAppearOnceInTheList);

View file

@ -221,15 +221,16 @@ fn calc_unused_spans(
}
}
pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
for directive in resolver.potentially_unused_imports.iter() {
impl Resolver<'_> {
crate fn check_unused(&mut self, krate: &ast::Crate) {
for directive in self.potentially_unused_imports.iter() {
match directive.subclass {
_ if directive.used.get() ||
directive.vis.get() == ty::Visibility::Public ||
directive.span.is_dummy() => {
if let ImportDirectiveSubclass::MacroUse = directive.subclass {
if !directive.span.is_dummy() {
resolver.session.buffer_lint(
self.session.buffer_lint(
lint::builtin::MACRO_USE_EXTERN_CRATE,
directive.id,
directive.span,
@ -242,19 +243,19 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
}
}
ImportDirectiveSubclass::ExternCrate { .. } => {
resolver.maybe_unused_extern_crates.push((directive.id, directive.span));
self.maybe_unused_extern_crates.push((directive.id, directive.span));
}
ImportDirectiveSubclass::MacroUse => {
let lint = lint::builtin::UNUSED_IMPORTS;
let msg = "unused `#[macro_use]` import";
resolver.session.buffer_lint(lint, directive.id, directive.span, msg);
self.session.buffer_lint(lint, directive.id, directive.span, msg);
}
_ => {}
}
}
let mut visitor = UnusedImportCheckVisitor {
r: resolver,
r: self,
unused_imports: Default::default(),
base_use_tree: None,
base_id: ast::DUMMY_NODE_ID,
@ -318,3 +319,4 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
);
}
}
}

View file

@ -1,7 +1,8 @@
use std::cmp::Reverse;
use errors::{Applicability, DiagnosticBuilder};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use log::debug;
use rustc::bug;
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
use rustc::hir::def::Namespace::{self, *};
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
@ -11,14 +12,16 @@ use rustc::util::nodemap::FxHashSet;
use syntax::ast::{self, Ident, Path};
use syntax::ext::base::MacroKind;
use syntax::feature_gate::BUILTIN_ATTRIBUTES;
use syntax::source_map::SourceMap;
use syntax::struct_span_err;
use syntax::symbol::{Symbol, kw};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{BytePos, Span};
use syntax_pos::{BytePos, Span, MultiSpan};
use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
use crate::{path_names_to_string, KNOWN_TOOLS};
use crate::{CrateLint, LegacyScope, Module, ModuleOrUniformRoot};
use crate::{PathResult, ParentScope, Resolver, Scope, ScopeSet, Segment};
use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};
type Res = def::Res<ast::NodeId>;
@ -42,6 +45,19 @@ crate struct ImportSuggestion {
pub path: Path,
}
/// Adjust the impl span so that just the `impl` keyword is taken by removing
/// everything after `<` (`"impl<T> Iterator for A<T> {}" -> "impl"`) and
/// everything after the first whitespace (`"impl Iterator for A" -> "impl"`).
///
/// *Attention*: the method used is very fragile since it essentially duplicates the work of the
/// parser. If you need to use this function or something similar, please consider updating the
/// `source_map` functions and this function to something more robust.
fn reduce_impl_span_to_impl_keyword(cm: &SourceMap, impl_span: Span) -> Span {
let impl_span = cm.span_until_char(impl_span, '<');
let impl_span = cm.span_until_whitespace(impl_span);
impl_span
}
crate fn add_typo_suggestion(
err: &mut DiagnosticBuilder<'_>, suggestion: Option<TypoSuggestion>, span: Span
) -> bool {
@ -71,6 +87,269 @@ crate fn add_module_candidates(
}
impl<'a> Resolver<'a> {
/// Combines an error with provided span and emits it.
///
/// This takes the error provided, combines it with the span and any additional spans inside the
/// error and emits it.
crate fn report_error(&self, span: Span, resolution_error: ResolutionError<'_>) {
self.into_struct_error(span, resolution_error).emit();
}
crate fn into_struct_error(
&self, span: Span, resolution_error: ResolutionError<'_>
) -> DiagnosticBuilder<'_> {
match resolution_error {
ResolutionError::GenericParamsFromOuterFunction(outer_res) => {
let mut err = struct_span_err!(self.session,
span,
E0401,
"can't use generic parameters from outer function",
);
err.span_label(span, format!("use of generic parameter from outer function"));
let cm = self.session.source_map();
match outer_res {
Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
if let Some(impl_span) = maybe_impl_defid.and_then(|def_id| {
self.definitions.opt_span(def_id)
}) {
err.span_label(
reduce_impl_span_to_impl_keyword(cm, impl_span),
"`Self` type implicitly declared here, by this `impl`",
);
}
match (maybe_trait_defid, maybe_impl_defid) {
(Some(_), None) => {
err.span_label(span, "can't use `Self` here");
}
(_, Some(_)) => {
err.span_label(span, "use a type here instead");
}
(None, None) => bug!("`impl` without trait nor type?"),
}
return err;
},
Res::Def(DefKind::TyParam, def_id) => {
if let Some(span) = self.definitions.opt_span(def_id) {
err.span_label(span, "type parameter from outer function");
}
}
Res::Def(DefKind::ConstParam, def_id) => {
if let Some(span) = self.definitions.opt_span(def_id) {
err.span_label(span, "const parameter from outer function");
}
}
_ => {
bug!("GenericParamsFromOuterFunction should only be used with Res::SelfTy, \
DefKind::TyParam");
}
}
// Try to retrieve the span of the function signature and generate a new message
// with a local type or const parameter.
let sugg_msg = &format!("try using a local generic parameter instead");
if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) {
// Suggest the modification to the user
err.span_suggestion(
sugg_span,
sugg_msg,
new_snippet,
Applicability::MachineApplicable,
);
} else if let Some(sp) = cm.generate_fn_name_span(span) {
err.span_label(sp,
format!("try adding a local generic parameter in this method instead"));
} else {
err.help(&format!("try using a local generic parameter instead"));
}
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 list of generic parameters",
name);
err.span_label(span, "already used");
err.span_label(first_use_span, format!("first use of `{}`", name));
err
}
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
let mut err = struct_span_err!(self.session,
span,
E0407,
"method `{}` is not a member of trait `{}`",
method,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
let mut err = struct_span_err!(self.session,
span,
E0437,
"type `{}` is not a member of trait `{}`",
type_,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
let mut err = struct_span_err!(self.session,
span,
E0438,
"const `{}` is not a member of trait `{}`",
const_,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::VariableNotBoundInPattern(binding_error) => {
let target_sp = binding_error.target.iter().cloned().collect::<Vec<_>>();
let msp = MultiSpan::from_spans(target_sp.clone());
let msg = format!("variable `{}` is not bound in all patterns", binding_error.name);
let mut err = self.session.struct_span_err_with_code(
msp,
&msg,
DiagnosticId::Error("E0408".into()),
);
for sp in target_sp {
err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name));
}
let origin_sp = binding_error.origin.iter().cloned();
for sp in origin_sp {
err.span_label(sp, "variable not in all patterns");
}
err
}
ResolutionError::VariableBoundWithDifferentMode(variable_name,
first_binding_span) => {
let mut err = struct_span_err!(self.session,
span,
E0409,
"variable `{}` is bound in inconsistent \
ways within the same match arm",
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,
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
}
ResolutionError::UndeclaredLabel(name, lev_candidate) => {
let mut err = struct_span_err!(self.session,
span,
E0426,
"use of undeclared label `{}`",
name);
if let Some(lev_candidate) = lev_candidate {
err.span_suggestion(
span,
"a label with a similar name exists in this scope",
lev_candidate.to_string(),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(span, format!("undeclared label `{}`", name));
}
err
}
ResolutionError::SelfImportsOnlyAllowedWithin => {
struct_span_err!(self.session,
span,
E0429,
"{}",
"`self` imports are only allowed within a { } list")
}
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
}
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
}
ResolutionError::FailedToResolve { label, suggestion } => {
let mut err = struct_span_err!(self.session, span, E0433,
"failed to resolve: {}", &label);
err.span_label(span, label);
if let Some((suggestions, msg, applicability)) = suggestion {
err.multipart_suggestion(&msg, suggestions, applicability);
}
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
}
ResolutionError::AttemptToUseNonConstantValueInConstant => {
let mut err = struct_span_err!(self.session, span, E0435,
"attempt to use a non-constant value in a constant");
err.span_label(span, "non-constant value");
err
}
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
let shadows_what = binding.descr();
let mut err = struct_span_err!(self.session, span, E0530, "{}s cannot shadow {}s",
what_binding, shadows_what);
err.span_label(span, format!("cannot be named the same as {} {}",
binding.article(), shadows_what));
let participle = if binding.is_import() { "imported" } else { "defined" };
let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
err.span_label(binding.span, msg);
err
}
ResolutionError::ForwardDeclaredTyParam => {
let mut err = struct_span_err!(self.session, span, E0128,
"type parameters with a default cannot use \
forward declared identifiers");
err.span_label(
span, "defaulted type parameters cannot be forward declared".to_string());
err
}
ResolutionError::ConstParamDependentOnTypeParam => {
let mut err = struct_span_err!(
self.session,
span,
E0671,
"const parameters cannot depend on type parameters"
);
err.span_label(span, format!("const parameter depends on type parameter"));
err
}
}
}
/// Lookup typo candidate in scope for a macro or import.
fn early_lookup_typo_candidate(
&mut self,

View file

@ -1,8 +1,7 @@
use GenericParameters::*;
use crate::{path_names_to_string, resolve_error};
use crate::{AliasPossibility, BindingError, CrateLint, LexicalScopeBinding, Module};
use crate::{ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult};
use crate::{path_names_to_string, AliasPossibility, BindingError, CrateLint, LexicalScopeBinding};
use crate::{Module, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult};
use crate::{PathSource, ResolutionError, Resolver, Rib, RibKind, Segment, UseError};
use crate::RibKind::*;
@ -582,7 +581,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
ident.name,
*span,
);
resolve_error(&self.r, param.ident.span, err);
self.r.report_error(param.ident.span, err);
}
seen_bindings.entry(ident).or_insert(param.ident.span);
@ -604,7 +603,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
ident.name,
*span,
);
resolve_error(&self.r, param.ident.span, err);
self.r.report_error(param.ident.span, err);
}
seen_bindings.entry(ident).or_insert(param.ident.span);
@ -873,7 +872,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
span,
).is_err() {
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
resolve_error(&self.r, span, err(ident.name, &path_names_to_string(path)));
self.r.report_error(span, err(ident.name, &path_names_to_string(path)));
}
}
}
@ -971,15 +970,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
let mut missing_vars = missing_vars.iter().collect::<Vec<_>>();
missing_vars.sort();
for (_, v) in missing_vars {
resolve_error(&self.r,
*v.origin.iter().next().unwrap(),
ResolutionError::VariableNotBoundInPattern(v));
self.r.report_error(
*v.origin.iter().next().unwrap(), ResolutionError::VariableNotBoundInPattern(v)
);
}
let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
inconsistent_vars.sort();
for (name, v) in inconsistent_vars {
let err = ResolutionError::VariableBoundWithDifferentMode(*name, v.1);
resolve_error(&self.r, v.0, err);
self.r.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
}
}
@ -1067,8 +1065,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
match bindings.get(&ident).cloned() {
Some(id) if id == outer_pat_id => {
// `Variant(a, a)`, error
resolve_error(
&self.r,
self.r.report_error(
ident.span,
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
&ident.as_str())
@ -1076,8 +1073,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
}
Some(..) if pat_src == PatternSource::FnParam => {
// `fn f(a: u8, a: u8)`, error
resolve_error(
&self.r,
self.r.report_error(
ident.span,
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
&ident.as_str())
@ -1141,8 +1137,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
// to something unusable as a pattern (e.g., constructor function),
// but we still conservatively report an error, see
// issues/33118#issuecomment-233962221 for one reason why.
resolve_error(
&self.r,
self.r.report_error(
ident.span,
ResolutionError::BindingShadowsSomethingUnacceptable(
pat_src.descr(), ident.name, binding.unwrap())
@ -1448,8 +1443,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
PartialRes::new(module.res().unwrap()),
PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
let err = ResolutionError::FailedToResolve { label, suggestion };
resolve_error(&self.r, span, err);
self.r.report_error(span, ResolutionError::FailedToResolve { label, suggestion });
PartialRes::new(Res::Err)
}
PathResult::Module(..) | PathResult::Failed { .. } => return None,
@ -1539,10 +1533,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
find_best_match_for_name(names, &*ident.as_str(), None)
});
self.r.record_partial_res(expr.id, PartialRes::new(Res::Err));
resolve_error(&self.r,
self.r.report_error(
label.ident.span,
ResolutionError::UndeclaredLabel(&label.ident.as_str(),
close_match));
ResolutionError::UndeclaredLabel(&label.ident.as_str(), close_match),
);
}
Some(node_id) => {
// Since this res is a label, it is never read.

View file

@ -33,7 +33,6 @@ use rustc::{bug, span_bug};
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::CStore;
use syntax::source_map::SourceMap;
use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext};
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives};
@ -45,8 +44,8 @@ use syntax::ast::{CRATE_NODE_ID, Crate, Expr, ExprKind};
use syntax::ast::{ItemKind, Path};
use syntax::{span_err, struct_span_err, unwrap_or};
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use syntax_pos::{Span, DUMMY_SP};
use errors::{Applicability, DiagnosticBuilder};
use log::debug;
@ -200,285 +199,6 @@ enum ResolutionError<'a> {
ConstParamDependentOnTypeParam,
}
/// Combines an error with provided span and emits it.
///
/// This takes the error provided, combines it with the span and any additional spans inside the
/// error and emits it.
fn resolve_error(resolver: &Resolver<'_>,
span: Span,
resolution_error: ResolutionError<'_>) {
resolve_struct_error(resolver, span, resolution_error).emit();
}
fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
span: Span,
resolution_error: ResolutionError<'a>)
-> DiagnosticBuilder<'sess> {
match resolution_error {
ResolutionError::GenericParamsFromOuterFunction(outer_res) => {
let mut err = struct_span_err!(resolver.session,
span,
E0401,
"can't use generic parameters from outer function",
);
err.span_label(span, format!("use of generic parameter from outer function"));
let cm = resolver.session.source_map();
match outer_res {
Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
if let Some(impl_span) = maybe_impl_defid.and_then(|def_id| {
resolver.definitions.opt_span(def_id)
}) {
err.span_label(
reduce_impl_span_to_impl_keyword(cm, impl_span),
"`Self` type implicitly declared here, by this `impl`",
);
}
match (maybe_trait_defid, maybe_impl_defid) {
(Some(_), None) => {
err.span_label(span, "can't use `Self` here");
}
(_, Some(_)) => {
err.span_label(span, "use a type here instead");
}
(None, None) => bug!("`impl` without trait nor type?"),
}
return err;
},
Res::Def(DefKind::TyParam, def_id) => {
if let Some(span) = resolver.definitions.opt_span(def_id) {
err.span_label(span, "type parameter from outer function");
}
}
Res::Def(DefKind::ConstParam, def_id) => {
if let Some(span) = resolver.definitions.opt_span(def_id) {
err.span_label(span, "const parameter from outer function");
}
}
_ => {
bug!("GenericParamsFromOuterFunction should only be used with Res::SelfTy, \
DefKind::TyParam");
}
}
// Try to retrieve the span of the function signature and generate a new message with
// a local type or const parameter.
let sugg_msg = &format!("try using a local generic parameter instead");
if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) {
// Suggest the modification to the user
err.span_suggestion(
sugg_span,
sugg_msg,
new_snippet,
Applicability::MachineApplicable,
);
} else if let Some(sp) = cm.generate_fn_name_span(span) {
err.span_label(sp,
format!("try adding a local generic parameter in this method instead"));
} else {
err.help(&format!("try using a local generic parameter instead"));
}
err
}
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
let mut err = struct_span_err!(resolver.session,
span,
E0403,
"the name `{}` is already used for a generic \
parameter in this list of generic parameters",
name);
err.span_label(span, "already used");
err.span_label(first_use_span, format!("first use of `{}`", name));
err
}
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
let mut err = struct_span_err!(resolver.session,
span,
E0407,
"method `{}` is not a member of trait `{}`",
method,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
let mut err = struct_span_err!(resolver.session,
span,
E0437,
"type `{}` is not a member of trait `{}`",
type_,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
let mut err = struct_span_err!(resolver.session,
span,
E0438,
"const `{}` is not a member of trait `{}`",
const_,
trait_);
err.span_label(span, format!("not a member of trait `{}`", trait_));
err
}
ResolutionError::VariableNotBoundInPattern(binding_error) => {
let target_sp = binding_error.target.iter().cloned().collect::<Vec<_>>();
let msp = MultiSpan::from_spans(target_sp.clone());
let msg = format!("variable `{}` is not bound in all patterns", binding_error.name);
let mut err = resolver.session.struct_span_err_with_code(
msp,
&msg,
DiagnosticId::Error("E0408".into()),
);
for sp in target_sp {
err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name));
}
let origin_sp = binding_error.origin.iter().cloned();
for sp in origin_sp {
err.span_label(sp, "variable not in all patterns");
}
err
}
ResolutionError::VariableBoundWithDifferentMode(variable_name,
first_binding_span) => {
let mut err = struct_span_err!(resolver.session,
span,
E0409,
"variable `{}` is bound in inconsistent \
ways within the same match arm",
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!(resolver.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!(resolver.session,
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
}
ResolutionError::UndeclaredLabel(name, lev_candidate) => {
let mut err = struct_span_err!(resolver.session,
span,
E0426,
"use of undeclared label `{}`",
name);
if let Some(lev_candidate) = lev_candidate {
err.span_suggestion(
span,
"a label with a similar name exists in this scope",
lev_candidate.to_string(),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(span, format!("undeclared label `{}`", name));
}
err
}
ResolutionError::SelfImportsOnlyAllowedWithin => {
struct_span_err!(resolver.session,
span,
E0429,
"{}",
"`self` imports are only allowed within a { } list")
}
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
let mut err = struct_span_err!(resolver.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
}
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
let mut err = struct_span_err!(resolver.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
}
ResolutionError::FailedToResolve { label, suggestion } => {
let mut err = struct_span_err!(resolver.session, span, E0433,
"failed to resolve: {}", &label);
err.span_label(span, label);
if let Some((suggestions, msg, applicability)) = suggestion {
err.multipart_suggestion(&msg, suggestions, applicability);
}
err
}
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
let mut err = struct_span_err!(resolver.session,
span,
E0434,
"{}",
"can't capture dynamic environment in a fn item");
err.help("use the `|| { ... }` closure form instead");
err
}
ResolutionError::AttemptToUseNonConstantValueInConstant => {
let mut err = struct_span_err!(resolver.session, span, E0435,
"attempt to use a non-constant value in a constant");
err.span_label(span, "non-constant value");
err
}
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
let shadows_what = binding.descr();
let mut err = struct_span_err!(resolver.session, span, E0530, "{}s cannot shadow {}s",
what_binding, shadows_what);
err.span_label(span, format!("cannot be named the same as {} {}",
binding.article(), shadows_what));
let participle = if binding.is_import() { "imported" } else { "defined" };
let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
err.span_label(binding.span, msg);
err
}
ResolutionError::ForwardDeclaredTyParam => {
let mut err = struct_span_err!(resolver.session, span, E0128,
"type parameters with a default cannot use \
forward declared identifiers");
err.span_label(
span, "defaulted type parameters cannot be forward declared".to_string());
err
}
ResolutionError::ConstParamDependentOnTypeParam => {
let mut err = struct_span_err!(
resolver.session,
span,
E0671,
"const parameters cannot depend on type parameters"
);
err.span_label(span, format!("const parameter depends on type parameter"));
err
}
}
}
/// Adjust the impl span so that just the `impl` keyword is taken by removing
/// everything after `<` (`"impl<T> Iterator for A<T> {}" -> "impl"`) and
/// everything after the first whitespace (`"impl Iterator for A" -> "impl"`).
///
/// *Attention*: the method used is very fragile since it essentially duplicates the work of the
/// parser. If you need to use this function or something similar, please consider updating the
/// `source_map` functions and this function to something more robust.
fn reduce_impl_span_to_impl_keyword(cm: &SourceMap, impl_span: Span) -> Span {
let impl_span = cm.span_until_char(impl_span, '<');
let impl_span = cm.span_until_whitespace(impl_span);
impl_span
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum AliasPossibility {
No,
@ -1503,7 +1223,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
match self.resolve_ast_path_inner(path, is_value) {
Ok(r) => r,
Err((span, error)) => {
resolve_error(self, span, error);
self.report_error(span, error);
Res::Err
}
}
@ -1736,7 +1456,7 @@ impl<'a> Resolver<'a> {
self.late_resolve_crate(krate);
check_unused::check_crate(self, krate);
self.check_unused(krate);
self.report_errors(krate);
self.crate_loader.postprocess(krate);
}
@ -2581,7 +2301,7 @@ impl<'a> Resolver<'a> {
// An invalid forward use of a type parameter from a previous default.
if let ForwardTyParamBanRibKind = all_ribs[rib_index].kind {
if record_used {
resolve_error(self, span, ResolutionError::ForwardDeclaredTyParam);
self.report_error(span, ResolutionError::ForwardDeclaredTyParam);
}
assert_eq!(res, Res::Err);
return Res::Err;
@ -2590,7 +2310,7 @@ impl<'a> Resolver<'a> {
// An invalid use of a type parameter as the type of a const parameter.
if let TyParamAsConstParamTy = all_ribs[rib_index].kind {
if record_used {
resolve_error(self, span, ResolutionError::ConstParamDependentOnTypeParam);
self.report_error(span, ResolutionError::ConstParamDependentOnTypeParam);
}
assert_eq!(res, Res::Err);
return Res::Err;
@ -2622,14 +2342,14 @@ impl<'a> Resolver<'a> {
ConstantItemRibKind => {
// Still doesn't deal with upvars
if record_used {
resolve_error(self, span, AttemptToUseNonConstantValueInConstant);
self.report_error(span, AttemptToUseNonConstantValueInConstant);
}
return Res::Err;
}
}
}
if let Some(res_err) = res_err {
resolve_error(self, span, res_err);
self.report_error(span, res_err);
return Res::Err;
}
}
@ -2644,10 +2364,8 @@ impl<'a> Resolver<'a> {
ItemRibKind | FnItemRibKind => {
// This was an attempt to use a type parameter outside its scope.
if record_used {
resolve_error(
self,
span,
ResolutionError::GenericParamsFromOuterFunction(res),
self.report_error(
span, ResolutionError::GenericParamsFromOuterFunction(res)
);
}
return Res::Err;
@ -2667,10 +2385,8 @@ impl<'a> Resolver<'a> {
if let ItemRibKind | FnItemRibKind = rib.kind {
// This was an attempt to use a const parameter outside its scope.
if record_used {
resolve_error(
self,
span,
ResolutionError::GenericParamsFromOuterFunction(res),
self.report_error(
span, ResolutionError::GenericParamsFromOuterFunction(res)
);
}
return Res::Err;
@ -2773,8 +2489,9 @@ impl<'a> Resolver<'a> {
ty::Visibility::Public
}
PathResult::Failed { span, label, suggestion, .. } => {
let err = ResolutionError::FailedToResolve { label, suggestion };
resolve_error(self, span, err);
self.report_error(
span, ResolutionError::FailedToResolve { label, suggestion }
);
ty::Visibility::Public
}
PathResult::Indeterminate => {

View file

@ -1,8 +1,7 @@
use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
use crate::{resolve_error, KNOWN_TOOLS};
use crate::ModuleOrUniformRoot;
use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
use crate::Namespace::*;
use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
use crate::resolve_imports::ImportResolver;
@ -768,7 +767,7 @@ impl<'a> Resolver<'a> {
(path_span, format!("partially resolved path in {} {}",
kind.article(), kind.descr()))
};
resolve_error(self, span, ResolutionError::FailedToResolve {
self.report_error(span, ResolutionError::FailedToResolve {
label,
suggestion: None
});

View file

@ -5,9 +5,8 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, ParentScope
use crate::Determinacy::{self, *};
use crate::Namespace::{self, TypeNS, MacroNS};
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use crate::{Resolver, Segment};
use crate::{Resolver, ResolutionError, Segment};
use crate::{names_to_string, module_to_string};
use crate::{resolve_error, ResolutionError};
use crate::ModuleKind;
use crate::build_reduced_graph::BuildReducedGraphVisitor;
use crate::diagnostics::Suggestion;
@ -913,7 +912,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
resolve_error(&self.r, span, ResolutionError::FailedToResolve {
self.r.report_error(span, ResolutionError::FailedToResolve {
label,
suggestion,
});