summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/diagnostics.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_resolve/src/diagnostics.rs
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_resolve/src/diagnostics.rs')
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs84
1 files changed, 47 insertions, 37 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 7add59ac6..0c9d30608 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -12,10 +12,10 @@ 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::{DefIdTree, TyCtxt};
+use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE;
use rustc_session::lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS;
use rustc_session::lint::BuiltinLintDiagnostics;
@@ -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)
@@ -1197,7 +1194,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
segms.push(ast::PathSegment::from_ident(ident));
let path = Path { span: name_binding.span, segments: segms, tokens: None };
let did = match res {
- Res::Def(DefKind::Ctor(..), did) => this.opt_parent(did),
+ Res::Def(DefKind::Ctor(..), did) => this.tcx.opt_parent(did),
_ => res.opt_def_id(),
};
@@ -1216,15 +1213,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// a note about editions
let note = if let Some(did) = did {
let requires_note = !did.is_local()
- && this.cstore().item_attrs_untracked(did, this.tcx.sess).any(
+ && this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any(
|attr| {
- if attr.has_name(sym::rustc_diagnostic_item) {
- [sym::TryInto, sym::TryFrom, sym::FromIterator]
- .map(|x| Some(x))
- .contains(&attr.value_str())
- } else {
- false
- }
+ [sym::TryInto, sym::TryFrom, sym::FromIterator]
+ .map(|x| Some(x))
+ .contains(&attr.value_str())
},
);
@@ -1373,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) {
@@ -1450,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`
@@ -1591,9 +1580,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ctor_def_id,
)) = binding.kind
{
- let def_id = self.parent(ctor_def_id);
- let fields = self.field_names.get(&def_id)?;
- return fields.iter().map(|name| name.span).reduce(Span::to); // None for `struct Foo()`
+ let def_id = self.tcx.parent(ctor_def_id);
+ return self
+ .field_def_ids(def_id)?
+ .iter()
+ .map(|&field_id| self.def_span(field_id))
+ .reduce(Span::to); // None for `struct Foo()`
}
None
}
@@ -1615,7 +1607,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut err =
struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident);
err.span_label(ident.span, &format!("private {}", descr));
- if let Some(span) = ctor_fields_span {
+
+ let mut non_exhaustive = None;
+ // If an ADT is foreign and marked as `non_exhaustive`, then that's
+ // probably why we have the privacy error.
+ // Otherwise, point out if the struct has any private fields.
+ if let Some(def_id) = res.opt_def_id()
+ && !def_id.is_local()
+ && let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive)
+ {
+ non_exhaustive = Some(attr.span);
+ } else if let Some(span) = ctor_fields_span {
err.span_label(span, "a constructor is private if any of the fields is private");
if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) {
err.multipart_suggestion_verbose(
@@ -1664,6 +1666,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if !first && binding.vis.is_public() {
note_span.push_span_label(def_span, "consider importing it directly");
}
+ // Final step in the import chain, point out if the ADT is `non_exhaustive`
+ // which is probably why this privacy violation occurred.
+ if next_binding.is_none() && let Some(span) = non_exhaustive {
+ note_span.push_span_label(
+ span,
+ format!("cannot be constructed because it is `#[non_exhaustive]`"),
+ );
+ }
err.span_note(note_span, &msg);
}
@@ -1677,8 +1687,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
) -> Option<Symbol> {
let mut candidates = self
.extern_prelude
- .iter()
- .map(|(ident, _)| ident.name)
+ .keys()
+ .map(|ident| ident.name)
.chain(
self.module_map
.iter()
@@ -2015,7 +2025,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// 1) some consistent ordering for emitted diagnostics, and
// 2) `std` suggestions before `core` suggestions.
let mut extern_crate_names =
- self.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
+ self.extern_prelude.keys().map(|ident| ident.name).collect::<Vec<_>>();
extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap());
for name in extern_crate_names.into_iter() {