Skip to content

Commit ebdddb5

Browse files
Rollup merge of #162942 - nnethercote:rm-StashKey-AssociatedTypeSuggestion, r=davidtwco
Remove `StashKey::AssociatedTypeSuggestion` Currently it's used in a really hacky way: a diagnostic with an empty message and some suggestions is stashed. Later on it might be retrieved and its suggestions extracted. It uses `Level::Allow` so that it isn't printed by `emit_stashed_diagnostics` at shutdown if it hasn't been retrieved. This isn't a normal stashed diagnostic, more just a case of "save some information that might be useful for diagnostics later". We can record the information more simply and directly. This commit adds `paths_matching_assoc_types` fields to `Resolver` and `ResolverGlobalCtxt`. These store the spans of the paths of interest. The new subdiagnostic `AssocTypeWithSameName` is used to construct the relevant suggestions when they are needed. Much nicer. The old approach removed the stashed diagnostic and the new approach doesn't remove the set entry, so a single span could conceivably match more than once, presumably a good thing, though this doesn't show up in the test suite. r? @davidtwco
2 parents 795a915 + 1e185bd commit ebdddb5

7 files changed

Lines changed: 41 additions & 32 deletions

File tree

‎compiler/rustc_errors/src/lib.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ pub enum StashKey {
384384
/// FRU syntax
385385
MaybeFruTypo,
386386
CallAssocMethod,
387-
AssociatedTypeSuggestion,
388387
UndeterminedMacroResolution,
389388
/// Used by `Parser::maybe_recover_trailing_expr`
390389
ExprInPat,

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ use rustc_ast::TraitObjectSyntax;
22
use rustc_attr_ir::lang_items::LangItem;
33
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
44
use rustc_errors::codes::*;
5-
use rustc_errors::{
6-
Applicability, Diag, DiagCtxtHandle, Diagnostic, Level, StashKey, Suggestions,
7-
struct_span_code_err,
8-
};
5+
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level, struct_span_code_err};
96
use rustc_hir::def::{DefKind, Res};
107
use rustc_hir::def_id::DefId;
118
use rustc_hir::{self as hir, HirId};
@@ -17,6 +14,7 @@ use rustc_middle::ty::{
1714
};
1815
use rustc_span::edit_distance::find_best_match_for_name;
1916
use rustc_span::{ErrorGuaranteed, Span};
17+
use rustc_trait_selection::diagnostics::AssocTypeWithSameName;
2018
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
2119
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
2220
use rustc_trait_selection::traits;
@@ -655,15 +653,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
655653
poly_trait_ref.trait_ref.trait_def_id(),
656654
&mut diag,
657655
);
658-
// In case there is an associated type with the same name
659-
// Add the suggestion to this error
660-
if let Some(mut sugg) =
661-
self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
662-
&& let Suggestions::Enabled(ref mut s1) = diag.suggestions
663-
&& let Suggestions::Enabled(ref mut s2) = sugg.suggestions
656+
// If there is an associated type with the same name, add the suggestion to this error.
657+
if self
658+
.tcx()
659+
.resolutions(())
660+
.paths_matching_assoc_types
661+
.contains(&span.with_parent(None))
664662
{
665-
s1.append(s2);
666-
sugg.cancel();
663+
diag.subdiagnostic(AssocTypeWithSameName { span: span.shrink_to_lo() });
667664
}
668665
Some(diag.emit_err())
669666
} else {

‎compiler/rustc_middle/src/middle/resolve.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ pub struct ResolverGlobalCtxt {
180180
/// A list of proc macro LocalDefIds, written out in the order in which
181181
/// they are declared in the static array generated by proc_macro_harness.
182182
pub proc_macros: Vec<LocalDefId>,
183+
/// Path spans where the ident matches an associated type for an enclosing trait. Used to
184+
/// improve certain error messages.
185+
pub paths_matching_assoc_types: UnordSet<Span>,
183186
/// Mapping from ident span to path span for paths that don't exist as written, but that
184187
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
185188
pub confused_type_with_std_module: FxIndexMap<Span, Span>,

‎compiler/rustc_resolve/src/late.rs‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
2222
use rustc_errors::codes::*;
2323
use rustc_errors::{
2424
Applicability, Diag, DiagArgValue, Diagnostic, ErrorGuaranteed, IntoDiagArg, MultiSpan,
25-
StashKey, Suggestions, elided_lifetime_in_path_suggestion, pluralize,
25+
Suggestions, elided_lifetime_in_path_suggestion, pluralize,
2626
};
2727
use rustc_hir::def::Namespace::{self, *};
2828
use rustc_hir::def::{CtorKind, DefKind, NonMacroAttrKind, PerNS};
@@ -4823,7 +4823,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48234823
source,
48244824
) {
48254825
Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
4826-
// if we also have an associated type that matches the ident, stash a suggestion
4826+
// If we also have an associated type that matches the ident, record that.
48274827
if let Some(items) = self.diag_metadata.current_trait_assoc_items
48284828
&& let [Segment { ident, .. }] = path
48294829
&& items.iter().any(|item| {
@@ -4836,14 +4836,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48364836
}
48374837
})
48384838
{
4839-
let mut diag = self.r.tcx.dcx().struct_allow("");
4840-
diag.span_suggestion_verbose(
4841-
path_span.shrink_to_lo(),
4842-
"there is an associated type with the same name",
4843-
"Self::",
4844-
Applicability::MaybeIncorrect,
4845-
);
4846-
diag.stash(path_span, StashKey::AssociatedTypeSuggestion);
4839+
self.r.paths_matching_assoc_types.insert(path_span.with_parent(None));
48474840
}
48484841

48494842
if source.is_expected(res) || res == Res::Err {

‎compiler/rustc_resolve/src/lib.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,7 @@ pub struct Resolver<'ra, 'tcx> {
15291529
/// A list of proc macro LocalDefIds, written out in the order in which
15301530
/// they are declared in the static array generated by proc_macro_harness.
15311531
proc_macros: Vec<LocalDefId> = Vec::new(),
1532+
paths_matching_assoc_types: UnordSet<Span>,
15321533
confused_type_with_std_module: FxIndexMap<Span, Span>,
15331534

15341535
/// Names of items that were stripped out via cfg with their corresponding cfg meta item.
@@ -1892,6 +1893,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18921893
invocation_parents,
18931894
trait_impls: Default::default(),
18941895
confused_type_with_std_module: Default::default(),
1896+
paths_matching_assoc_types: Default::default(),
18951897
stripped_cfg_items: Default::default(),
18961898
effective_visibilities: Default::default(),
18971899
macro_reachable_adts: Default::default(),
@@ -1970,6 +1972,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19701972
let glob_map = self.glob_map;
19711973
let main_def = self.main_def;
19721974
let confused_type_with_std_module = self.confused_type_with_std_module;
1975+
let paths_matching_assoc_types = self.paths_matching_assoc_types;
19731976
let effective_visibilities = self.effective_visibilities;
19741977

19751978
let stripped_cfg_items = self
@@ -2000,6 +2003,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20002003
trait_impls: self.trait_impls,
20012004
proc_macros,
20022005
confused_type_with_std_module,
2006+
paths_matching_assoc_types,
20032007
doc_link_resolutions: self.doc_link_resolutions,
20042008
doc_link_traits_in_scope: self.doc_link_traits_in_scope,
20052009
all_macro_rules: self.all_macro_rules,

‎compiler/rustc_trait_selection/src/diagnostics.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,3 +2083,15 @@ pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
20832083
}")]
20842084
pub param_span: Span,
20852085
}
2086+
2087+
#[derive(Subdiagnostic)]
2088+
#[suggestion(
2089+
"there is an associated type with the same name",
2090+
style = "verbose",
2091+
code = "Self::",
2092+
applicability = "maybe-incorrect"
2093+
)]
2094+
pub struct AssocTypeWithSameName {
2095+
#[primary_span]
2096+
pub span: Span,
2097+
}

‎compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1313
use rustc_data_structures::unord::UnordSet;
1414
use rustc_errors::codes::*;
1515
use rustc_errors::{
16-
Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, StringPart, Sublevel, Suggestions,
17-
msg, pluralize, struct_span_code_err,
16+
Applicability, Diag, ErrorGuaranteed, MultiSpan, StringPart, Sublevel, msg, pluralize,
17+
struct_span_code_err,
1818
};
1919
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
2020
use rustc_hir::intravisit::Visitor;
@@ -42,7 +42,8 @@ use tracing::{debug, instrument};
4242
use super::suggestions::get_explanation_based_on_obligation;
4343
use super::{ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate};
4444
use crate::diagnostics::{
45-
ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, CoroClosureNotFn,
45+
AssocTypeWithSameName, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
46+
CoroClosureNotFn,
4647
};
4748
use crate::error_reporting::TypeErrCtxt;
4849
use crate::error_reporting::infer::TyCategory;
@@ -3107,13 +3108,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
31073108
);
31083109
self.suggest_unsized_bound_if_applicable(err, obligation);
31093110
if let Some(span) = err.span.primary_span()
3110-
&& let Some(mut diag) =
3111-
self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
3112-
&& let Suggestions::Enabled(ref mut s1) = err.suggestions
3113-
&& let Suggestions::Enabled(ref mut s2) = diag.suggestions
3111+
&& self
3112+
.tcx
3113+
.resolutions(())
3114+
.paths_matching_assoc_types
3115+
.contains(&span.with_parent(None))
31143116
{
3115-
s1.append(s2);
3116-
diag.cancel()
3117+
err.subdiagnostic(AssocTypeWithSameName { span: span.shrink_to_lo() });
31173118
}
31183119
}
31193120
}

0 commit comments

Comments
 (0)