Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 64 additions & 13 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub(crate) struct ImportSuggestion {
/// An extra note that should be issued if this item is suggested
pub note: Option<String>,
pub is_stable: bool,
pub is_exact_match: bool,
}

/// Adjust the impl span so that just the `impl` keyword is taken by removing
Expand Down Expand Up @@ -1360,16 +1361,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}

fn lookup_import_candidates_from_module<FilterFn>(
fn lookup_import_candidates_from_module<IdentFilterFn, FilterFn>(
&self,
lookup_ident: Ident,
namespace: Namespace,
parent_scope: &ParentScope<'ra>,
start_module: Module<'ra>,
crate_path: ThinVec<ast::PathSegment>,
ident_filter_fn: IdentFilterFn,
filter_fn: FilterFn,
) -> Vec<ImportSuggestion>
where
IdentFilterFn: Fn(Ident, Ident) -> bool,
FilterFn: Fn(Res) -> bool,
{
let mut candidates = Vec::new();
Expand Down Expand Up @@ -1441,7 +1444,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// collect results based on the filter function
// avoid suggesting anything from the same module in which we are resolving
// avoid suggesting anything with a hygienic name
if ident.name == lookup_ident.name
if ident_filter_fn(ident.orig(orig_ident_span), lookup_ident)
&& ns == namespace
&& in_module != parent_scope.module
&& ident.ctxt.is_root()
Expand Down Expand Up @@ -1521,6 +1524,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
note,
via_import,
is_stable,
is_exact_match: ident.name == lookup_ident.name,
});
}
}
Expand Down Expand Up @@ -1597,6 +1601,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
///
/// N.B., the method does not look into imports, but this is not a problem,
/// since we report the definitions (thus, the de-aliased imports).
///
/// The method is implemented in `lookup_import_candidates_impl`. The `_impl` method allows applying a different filter function on the ident than the exact match function used by default here.
pub(crate) fn lookup_import_candidates<FilterFn>(
&mut self,
lookup_ident: Ident,
Expand All @@ -1606,6 +1612,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
) -> Vec<ImportSuggestion>
where
FilterFn: Fn(Res) -> bool,
{
self.lookup_import_candidates_impl(
lookup_ident,
namespace,
parent_scope,
|ident: Ident, lookup_ident: Ident| ident.name == lookup_ident.name,
filter_fn,
)
}

/// The actual impl of the `lookup_import_candidates function`.
pub(crate) fn lookup_import_candidates_impl<IdentFilterFn, FilterFn>(
&mut self,
lookup_ident: Ident,
namespace: Namespace,
parent_scope: &ParentScope<'ra>,
ident_filter_fn: IdentFilterFn,
filter_fn: FilterFn,
) -> Vec<ImportSuggestion>
where
IdentFilterFn: Fn(Ident, Ident) -> bool,
FilterFn: Fn(Res) -> bool,
{
let crate_path = thin_vec![ast::PathSegment::from_ident(Ident::with_dummy_span(kw::Crate))];
let mut suggestions = self.lookup_import_candidates_from_module(
Expand All @@ -1614,6 +1642,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent_scope,
self.graph_root.to_module(),
crate_path,
&ident_filter_fn,
&filter_fn,
);

Expand Down Expand Up @@ -1670,6 +1699,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent_scope,
crate_root,
crate_path,
&ident_filter_fn,
&filter_fn,
));
}
Expand Down Expand Up @@ -3552,7 +3582,7 @@ pub(crate) fn import_candidates(
);
}

type PathString<'a> = (String, &'a str, Option<Span>, &'a Option<String>, bool);
type PathString<'a> = (String, &'a str, Option<Span>, &'a Option<String>, bool, bool);

/// When an entity with a given name is not available in scope, we search for
/// entities with that name in all crates. This method allows outputting the
Expand Down Expand Up @@ -3588,6 +3618,7 @@ fn show_candidates(
c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))),
&c.note,
c.via_import,
c.is_exact_match,
))
}
} else {
Expand All @@ -3597,6 +3628,7 @@ fn show_candidates(
c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))),
&c.note,
c.via_import,
c.is_exact_match,
))
}
});
Expand Down Expand Up @@ -3628,9 +3660,10 @@ fn show_candidates(

if !accessible_path_strings.is_empty() {
let (determiner, kind, s, name, through) =
if let [(name, descr, _, _, via_import)] = &accessible_path_strings[..] {
if let [(name, descr, _, _, via_import, is_exact_match)] = &accessible_path_strings[..]
{
(
"this",
if *is_exact_match { "this" } else { "this similarly named" },
*descr,
"",
format!(" `{name}`"),
Expand All @@ -3641,12 +3674,24 @@ fn show_candidates(
// instead of the more generic "items".
let kinds = accessible_path_strings
.iter()
.map(|(_, descr, _, _, _)| *descr)
.map(|(_, descr, _, _, _, _)| *descr)
.collect::<UnordSet<&str>>();
let kind = if let Some(kind) = kinds.get_only() { kind } else { "item" };
let s = if kind.ends_with('s') { "es" } else { "s" };
// we should only suggest case insensitive suggestion if no case sensitive match was found,
// so all the suggestion should have the same is_exact_match value.

("one of these", kind, s, String::new(), "")
(
if accessible_path_strings[0].5 {
"one of these"
} else {
"one of these similarly named"
},
kind,
s,
String::new(),
"",
)
};

let instead = if let Instead::Yes = instead { " instead" } else { "" };
Expand Down Expand Up @@ -3740,9 +3785,12 @@ fn show_candidates(
{
let prefix =
if let DiagMode::Pattern = mode { "you might have meant to match on " } else { "" };
if let [(name, descr, source_span, note, _)] = &inaccessible_path_strings[..] {
if let [(name, descr, source_span, note, _, is_exact_match)] =
&inaccessible_path_strings[..]
{
let msg = format!(
"{prefix}{descr} `{name}`{} exists but is inaccessible",
"{prefix}{}{descr} `{name}`{} exists but is inaccessible",
if *is_exact_match { "" } else { "similarly named " },
if let DiagMode::Pattern = mode { ", which" } else { "" }
);

Expand All @@ -3760,17 +3808,20 @@ fn show_candidates(
} else {
let descr = inaccessible_path_strings
.iter()
.map(|&(_, descr, _, _, _)| descr)
.map(|&(_, descr, _, _, _, _)| descr)
.all_equal_value()
.unwrap_or("item");
let plural_descr =
if descr.ends_with('s') { format!("{descr}es") } else { format!("{descr}s") };

let mut msg = format!("{prefix}these {plural_descr} exist but are inaccessible");
let are_exact_matches = inaccessible_path_strings[0].5;
let mut msg = format!(
"{prefix}these {}{plural_descr} exist but are inaccessible",
if are_exact_matches { "" } else { "similarly named " },
);
let mut has_colon = false;

let mut spans = Vec::new();
for (name, _, source_span, _, _) in &inaccessible_path_strings {
for (name, _, source_span, _, _, _) in &inaccessible_path_strings {
if let Some(source_span) = source_span {
let span = tcx.sess.source_map().guess_head_span(*source_span);
spans.push((name, span));
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ impl RibKind<'_> {
#[derive(Debug)]
pub(crate) struct Rib<'ra, R = Res> {
pub bindings: FxIndexMap<Ident, R>,
pub patterns_with_skipped_bindings: UnordMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,
pub patterns_with_skipped_bindings:
UnordMap<DefId, Vec<(Span, Option<Span>, Result<(), ErrorGuaranteed>)>>,
pub kind: RibKind<'ra>,
}

Expand Down Expand Up @@ -4322,6 +4323,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
.or_default()
.push((
pat.span,
match rest {
ast::PatFieldsRest::Rest(span) => Some(*span),
_ => None,
},
match rest {
ast::PatFieldsRest::Recovered(guar) => Err(*guar),
_ => Ok(()),
Expand Down Expand Up @@ -5631,6 +5636,18 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
.filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. }))
.count();
self.r.item_generics_num_lifetimes.insert(def_id, count);
let type_or_const_count = generics
.params
.iter()
.filter(|param| {
matches!(
param.kind,
ast::GenericParamKind::Type { .. }
| ast::GenericParamKind::Const { .. }
)
})
.count();
self.r.item_generics_num_type_or_const_params.insert(def_id, type_or_const_count);
}

ItemKind::ForeignMod(ForeignMod { items, .. }) => {
Expand Down
Loading
Loading