Skip to content

Commit d1d81a0

Browse files
introduce, implement and use SmartResolver
1 parent 7cd9505 commit d1d81a0

File tree

7 files changed

+852
-571
lines changed

7 files changed

+852
-571
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::imports::{ImportData, ImportKind};
3737
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3838
use crate::{
3939
BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
40-
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used,
40+
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, SmartResolver, Used,
4141
VisResolutionError, errors,
4242
};
4343

@@ -373,7 +373,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
373373
res,
374374
))
375375
};
376-
match self.r.resolve_path(
376+
match SmartResolver::finalize(self.r, finalize).resolve_path(
377377
&segments,
378378
None,
379379
parent_scope,

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 116 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ use crate::{
4545
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
4646
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
4747
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
48-
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
49-
VisResolutionError, errors as errs, path_names_to_string,
48+
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, SmartResolver, UseError,
49+
Used, VisResolutionError, errors as errs, path_names_to_string,
5050
};
5151

5252
type Res = def::Res<ast::NodeId>;
@@ -465,61 +465,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
465465
err.subdiagnostic(errors::RemoveUnnecessaryImport { span });
466466
}
467467

468-
pub(crate) fn lint_if_path_starts_with_module(
469-
&mut self,
470-
finalize: Option<Finalize>,
471-
path: &[Segment],
472-
second_binding: Option<NameBinding<'_>>,
473-
) {
474-
let Some(Finalize { node_id, root_span, .. }) = finalize else {
475-
return;
476-
};
477-
478-
let first_name = match path.get(0) {
479-
// In the 2018 edition this lint is a hard error, so nothing to do
480-
Some(seg) if seg.ident.span.is_rust_2015() && self.tcx.sess.is_rust_2015() => {
481-
seg.ident.name
482-
}
483-
_ => return,
484-
};
485-
486-
// We're only interested in `use` paths which should start with
487-
// `{{root}}` currently.
488-
if first_name != kw::PathRoot {
489-
return;
490-
}
491-
492-
match path.get(1) {
493-
// If this import looks like `crate::...` it's already good
494-
Some(Segment { ident, .. }) if ident.name == kw::Crate => return,
495-
// Otherwise go below to see if it's an extern crate
496-
Some(_) => {}
497-
// If the path has length one (and it's `PathRoot` most likely)
498-
// then we don't know whether we're gonna be importing a crate or an
499-
// item in our crate. Defer this lint to elsewhere
500-
None => return,
501-
}
502-
503-
// If the first element of our path was actually resolved to an
504-
// `ExternCrate` (also used for `crate::...`) then no need to issue a
505-
// warning, this looks all good!
506-
if let Some(binding) = second_binding
507-
&& let NameBindingKind::Import { import, .. } = binding.kind
508-
// Careful: we still want to rewrite paths from renamed extern crates.
509-
&& let ImportKind::ExternCrate { source: None, .. } = import.kind
510-
{
511-
return;
512-
}
513-
514-
let diag = BuiltinLintDiag::AbsPathWithModule(root_span);
515-
self.lint_buffer.buffer_lint(
516-
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
517-
node_id,
518-
root_span,
519-
diag,
520-
);
521-
}
522-
523468
pub(crate) fn add_module_candidates(
524469
&self,
525470
module: Module<'ra>,
@@ -1046,15 +991,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1046991
if filter_fn(res) {
1047992
for derive in parent_scope.derives {
1048993
let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
1049-
let Ok((Some(ext), _)) = this.resolve_macro_path(
1050-
derive,
1051-
Some(MacroKind::Derive),
1052-
parent_scope,
1053-
false,
1054-
false,
1055-
None,
1056-
None,
1057-
) else {
994+
let Ok((Some(ext), _)) = SmartResolver::Finalize(this)
995+
.resolve_macro_path(
996+
derive,
997+
Some(MacroKind::Derive),
998+
parent_scope,
999+
false,
1000+
false,
1001+
None,
1002+
None,
1003+
)
1004+
else {
10581005
continue;
10591006
};
10601007
suggestions.extend(
@@ -1589,15 +1536,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15891536
});
15901537
}
15911538
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
1592-
let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
1593-
ident,
1594-
ScopeSet::All(ns),
1595-
parent_scope,
1596-
None,
1597-
false,
1598-
None,
1599-
None,
1600-
) else {
1539+
let Ok(binding) = SmartResolver::Speculative(self)
1540+
.early_resolve_ident_in_lexical_scope(
1541+
ident,
1542+
ScopeSet::All(ns),
1543+
parent_scope,
1544+
None,
1545+
false,
1546+
None,
1547+
None,
1548+
)
1549+
else {
16011550
continue;
16021551
};
16031552

@@ -2269,21 +2218,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22692218
if ns == TypeNS || ns == ValueNS {
22702219
let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS };
22712220
let binding = if let Some(module) = module {
2272-
self.resolve_ident_in_module(
2273-
module,
2274-
ident,
2275-
ns_to_try,
2276-
parent_scope,
2277-
None,
2278-
ignore_binding,
2279-
ignore_import,
2280-
)
2281-
.ok()
2221+
SmartResolver::Speculative(self)
2222+
.resolve_ident_in_module(
2223+
module,
2224+
ident,
2225+
ns_to_try,
2226+
parent_scope,
2227+
None,
2228+
ignore_binding,
2229+
ignore_import,
2230+
)
2231+
.ok()
22822232
} else if let Some(ribs) = ribs
22832233
&& let Some(TypeNS | ValueNS) = opt_ns
22842234
{
22852235
assert!(ignore_import.is_none());
2286-
match self.resolve_ident_in_lexical_scope(
2236+
match SmartResolver::Speculative(self).resolve_ident_in_lexical_scope(
22872237
ident,
22882238
ns_to_try,
22892239
parent_scope,
@@ -2296,16 +2246,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22962246
_ => None,
22972247
}
22982248
} else {
2299-
self.early_resolve_ident_in_lexical_scope(
2300-
ident,
2301-
ScopeSet::All(ns_to_try),
2302-
parent_scope,
2303-
None,
2304-
false,
2305-
ignore_binding,
2306-
ignore_import,
2307-
)
2308-
.ok()
2249+
SmartResolver::Speculative(self)
2250+
.early_resolve_ident_in_lexical_scope(
2251+
ident,
2252+
ScopeSet::All(ns_to_try),
2253+
parent_scope,
2254+
None,
2255+
false,
2256+
ignore_binding,
2257+
ignore_import,
2258+
)
2259+
.ok()
23092260
};
23102261
if let Some(binding) = binding {
23112262
msg = format!(
@@ -2332,7 +2283,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
23322283
// Check whether the name refers to an item in the value namespace.
23332284
let binding = if let Some(ribs) = ribs {
23342285
assert!(ignore_import.is_none());
2335-
self.resolve_ident_in_lexical_scope(
2286+
SmartResolver::Speculative(self).resolve_ident_in_lexical_scope(
23362287
ident,
23372288
ValueNS,
23382289
parent_scope,
@@ -2399,15 +2350,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
23992350
},
24002351
)
24012352
});
2402-
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
2403-
ident,
2404-
ScopeSet::All(ValueNS),
2405-
parent_scope,
2406-
None,
2407-
false,
2408-
ignore_binding,
2409-
ignore_import,
2410-
) {
2353+
if let Ok(binding) = SmartResolver::Speculative(self)
2354+
.early_resolve_ident_in_lexical_scope(
2355+
ident,
2356+
ScopeSet::All(ValueNS),
2357+
parent_scope,
2358+
None,
2359+
false,
2360+
ignore_binding,
2361+
ignore_import,
2362+
)
2363+
{
24112364
let descr = binding.res().descr();
24122365
(format!("{descr} `{ident}` is not a crate or module"), suggestion)
24132366
} else {
@@ -3297,6 +3250,63 @@ fn show_candidates(
32973250
showed
32983251
}
32993252

3253+
impl<'r, 'ra, 'tcx> SmartResolver<'r, 'ra, 'tcx> {
3254+
pub(crate) fn lint_if_path_starts_with_module(
3255+
mut self,
3256+
finalize: Option<Finalize>,
3257+
path: &[Segment],
3258+
second_binding: Option<NameBinding<'_>>,
3259+
) {
3260+
let Some(Finalize { node_id, root_span, .. }) = finalize else {
3261+
return;
3262+
};
3263+
3264+
let first_name = match path.get(0) {
3265+
// In the 2018 edition this lint is a hard error, so nothing to do
3266+
Some(seg) if seg.ident.span.is_rust_2015() && self.tcx.sess.is_rust_2015() => {
3267+
seg.ident.name
3268+
}
3269+
_ => return,
3270+
};
3271+
3272+
// We're only interested in `use` paths which should start with
3273+
// `{{root}}` currently.
3274+
if first_name != kw::PathRoot {
3275+
return;
3276+
}
3277+
3278+
match path.get(1) {
3279+
// If this import looks like `crate::...` it's already good
3280+
Some(Segment { ident, .. }) if ident.name == kw::Crate => return,
3281+
// Otherwise go below to see if it's an extern crate
3282+
Some(_) => {}
3283+
// If the path has length one (and it's `PathRoot` most likely)
3284+
// then we don't know whether we're gonna be importing a crate or an
3285+
// item in our crate. Defer this lint to elsewhere
3286+
None => return,
3287+
}
3288+
3289+
// If the first element of our path was actually resolved to an
3290+
// `ExternCrate` (also used for `crate::...`) then no need to issue a
3291+
// warning, this looks all good!
3292+
if let Some(binding) = second_binding
3293+
&& let NameBindingKind::Import { import, .. } = binding.kind
3294+
// Careful: we still want to rewrite paths from renamed extern crates.
3295+
&& let ImportKind::ExternCrate { source: None, .. } = import.kind
3296+
{
3297+
return;
3298+
}
3299+
3300+
let diag = BuiltinLintDiag::AbsPathWithModule(root_span);
3301+
self.res_mut().lint_buffer.buffer_lint(
3302+
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
3303+
node_id,
3304+
root_span,
3305+
diag,
3306+
);
3307+
}
3308+
}
3309+
33003310
#[derive(Debug)]
33013311
struct UsePlacementFinder {
33023312
target_module: NodeId,

0 commit comments

Comments
 (0)