resolve: Centralize retrieval of items span and item name

This commit is contained in:
Vadim Petrochenkov 2023-02-22 11:14:20 +04:00
parent c7f424b80a
commit 2a716f3563
5 changed files with 37 additions and 69 deletions

View File

@ -130,12 +130,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
let expn_id = self.cstore().module_expansion_untracked(def_id, &self.tcx.sess);
let span = self.cstore().get_span_untracked(def_id, &self.tcx.sess);
Some(self.new_module(
parent,
ModuleKind::Def(def_kind, def_id, name),
expn_id,
span,
self.def_span(def_id),
// FIXME: Account for `#[no_implicit_prelude]` attributes.
parent.map_or(false, |module| module.no_implicit_prelude),
))

View File

@ -12,7 +12,7 @@ use rustc_errors::{struct_span_err, SuggestionStyle};
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
@ -555,25 +555,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return err;
}
Res::SelfTyAlias { alias_to: def_id, .. } => {
if let Some(impl_span) = self.opt_span(def_id) {
err.span_label(
reduce_impl_span_to_impl_keyword(sm, impl_span),
"`Self` type implicitly declared here, by this `impl`",
);
}
err.span_label(
reduce_impl_span_to_impl_keyword(sm, self.def_span(def_id)),
"`Self` type implicitly declared here, by this `impl`",
);
err.span_label(span, "use a type here instead");
return err;
}
Res::Def(DefKind::TyParam, def_id) => {
if let Some(span) = self.opt_span(def_id) {
err.span_label(span, "type parameter from outer function");
}
err.span_label(self.def_span(def_id), "type parameter from outer function");
def_id
}
Res::Def(DefKind::ConstParam, def_id) => {
if let Some(span) = self.opt_span(def_id) {
err.span_label(span, "const parameter from outer function");
}
err.span_label(
self.def_span(def_id),
"const parameter from outer function",
);
def_id
}
_ => {
@ -589,7 +586,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Try to retrieve the span of the function signature and generate a new
// message with a local type or const parameter.
let sugg_msg = "try using a local generic parameter instead";
let name = self.opt_name(def_id).unwrap_or(sym::T);
let name = self.tcx.item_name(def_id);
let (span, snippet) = if span.is_empty() {
let snippet = format!("<{}>", name);
(span, snippet)
@ -1369,8 +1366,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
if ident.name == kw::Default
&& let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind
&& let Some(span) = self.opt_span(def_id)
{
let span = self.def_span(def_id);
let source_map = self.tcx.sess.source_map();
let head_span = source_map.guess_head_span(span);
if let Ok(head) = source_map.span_to_snippet(head_span) {
@ -1446,11 +1443,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some(suggestion) if suggestion.candidate == kw::Underscore => return false,
Some(suggestion) => suggestion,
};
let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate {
LOCAL_CRATE => self.opt_span(def_id),
_ => Some(self.cstore().get_span_untracked(def_id, self.tcx.sess)),
});
if let Some(def_span) = def_span {
if let Some(def_span) = suggestion.res.opt_def_id().map(|def_id| self.def_span(def_id)) {
if span.overlaps(def_span) {
// Don't suggest typo suggestion for itself like in the following:
// error[E0423]: expected function, tuple struct or tuple variant, found struct `X`

View File

@ -3376,7 +3376,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
participle: "defined",
article: res.article(),
shadowed_binding: res,
shadowed_binding_span: self.r.opt_span(def_id).expect("const parameter defined outside of local crate"),
shadowed_binding_span: self.r.def_span(def_id),
}
);
None

View File

@ -19,7 +19,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_session::lint;
use rustc_session::parse::feature_err;
@ -166,13 +166,6 @@ impl TypoCandidate {
}
impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn def_span(&self, def_id: DefId) -> Option<Span> {
match def_id.krate {
LOCAL_CRATE => self.r.opt_span(def_id),
_ => Some(self.r.cstore().get_span_untracked(def_id, self.r.tcx.sess)),
}
}
fn make_base_error(
&mut self,
path: &[Segment],
@ -191,7 +184,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
span,
span_label: match res {
Res::Def(kind, def_id) if kind == DefKind::TyParam => {
self.def_span(def_id).map(|span| (span, "found this type parameter"))
Some((self.r.def_span(def_id), "found this type parameter"))
}
_ => None,
},
@ -1295,9 +1288,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
let span = find_span(&source, err);
if let Some(span) = self.def_span(def_id) {
err.span_label(span, &format!("`{}` defined here", path_str));
}
err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
let (tail, descr, applicability) = match source {
PathSource::Pat | PathSource::TupleStruct(..) => {
("", "pattern", Applicability::MachineApplicable)
@ -1359,17 +1350,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if self.r.tcx.sess.is_nightly_build() {
let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
`type` alias";
if let Some(span) = self.def_span(def_id) {
if let Ok(snip) = self.r.tcx.sess.source_map().span_to_snippet(span) {
// The span contains a type alias so we should be able to
// replace `type` with `trait`.
let snip = snip.replacen("type", "trait", 1);
err.span_suggestion(span, msg, snip, Applicability::MaybeIncorrect);
} else {
err.span_help(span, msg);
}
let span = self.r.def_span(def_id);
if let Ok(snip) = self.r.tcx.sess.source_map().span_to_snippet(span) {
// The span contains a type alias so we should be able to
// replace `type` with `trait`.
let snip = snip.replacen("type", "trait", 1);
err.span_suggestion(span, msg, snip, Applicability::MaybeIncorrect);
} else {
err.help(msg);
err.span_help(span, msg);
}
}
}
@ -1512,9 +1500,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
match source {
PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
let span = find_span(&source, err);
if let Some(span) = self.def_span(def_id) {
err.span_label(span, &format!("`{}` defined here", path_str));
}
err.span_label(
self.r.def_span(def_id),
&format!("`{path_str}` defined here"),
);
err.span_suggestion(
span,
"use this syntax instead",
@ -1527,9 +1516,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);
if let Some(span) = self.def_span(def_id) {
err.span_label(span, &format!("`{}` defined here", path_str));
}
err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
let fields = self.r.field_names.get(&def_id).map_or_else(
|| "/* fields */".to_string(),
|fields| vec!["_"; fields.len()].join(", "),
@ -2093,9 +2080,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
};
if def_id.is_local() {
if let Some(span) = self.def_span(def_id) {
err.span_note(span, "the enum is defined here");
}
err.span_note(self.r.def_span(def_id), "the enum is defined here");
}
}

View File

@ -48,7 +48,6 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::cstore::CrateStore;
use rustc_session::lint::LintBuffer;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
use rustc_span::source_map::Spanned;
@ -1870,20 +1869,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
/// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
#[inline]
fn opt_span(&self, def_id: DefId) -> Option<Span> {
def_id.as_local().map(|def_id| self.tcx.source_span(def_id))
}
/// Retrieves the name of the given `DefId`.
#[inline]
fn opt_name(&self, def_id: DefId) -> Option<Symbol> {
let def_key = match def_id.as_local() {
Some(def_id) => self.tcx.definitions_untracked().def_key(def_id),
None => self.cstore().def_key(def_id),
};
def_key.get_opt_name()
/// Retrieves definition span of the given `DefId`.
fn def_span(&self, def_id: DefId) -> Span {
match def_id.as_local() {
Some(def_id) => self.tcx.source_span(def_id),
None => self.cstore().get_span_untracked(def_id, self.tcx.sess),
}
}
/// Checks if an expression refers to a function marked with