Skip to content

Commit e7e1a39

Browse files
committed
suggest importing for partial mod path in name resolving
1 parent 38b44eb commit e7e1a39

8 files changed

+120
-20
lines changed

compiler/rustc_resolve/src/late.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -3556,9 +3556,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
35563556
_ => return Some(parent_err),
35573557
};
35583558

3559-
let (mut err, candidates) =
3559+
let (mut err, mut candidates) =
35603560
this.smart_resolve_report_errors(prefix_path, path_span, PathSource::Type, None);
35613561

3562+
if candidates.is_empty() {
3563+
candidates = this.smart_resolve_partial_mod_path_errors(prefix_path, path);
3564+
}
3565+
35623566
// There are two different error messages user might receive at
35633567
// this point:
35643568
// - E0412 cannot find type `{}` in this scope

compiler/rustc_resolve/src/late/diagnostics.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseS
44
use crate::{errors, path_names_to_string};
55
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
66
use crate::{PathResult, PathSource, Segment};
7+
use rustc_hir::def::Namespace::{self, *};
78

89
use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt};
910
use rustc_ast::{
@@ -17,7 +18,6 @@ use rustc_errors::{
1718
MultiSpan,
1819
};
1920
use rustc_hir as hir;
20-
use rustc_hir::def::Namespace::{self, *};
2121
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
2222
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
2323
use rustc_hir::PrimTy;
@@ -221,10 +221,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
221221
let suggestion = if self.current_trait_ref.is_none()
222222
&& let Some((fn_kind, _)) = self.diagnostic_metadata.current_function
223223
&& let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt()
224+
&& let FnKind::Fn(_, _, sig, ..) = fn_kind
224225
&& let Some(items) = self.diagnostic_metadata.current_impl_items
225226
&& let Some(item) = items.iter().find(|i| {
226227
if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind
227228
&& i.ident.name == item_str.name
229+
// don't suggest if the item is in Fn signature arguments
230+
// issue #112590
231+
&& !sig.span.contains(item_span)
228232
{
229233
debug!(?item_str.name);
230234
return true
@@ -318,6 +322,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
318322
}
319323
}
320324

325+
/// Try to suggest for a module path that cannot be resolved.
326+
/// Such as `fmt::Debug` where `fmt` is not resolved without importing,
327+
/// here we search with `lookup_import_candidates` for a module named `fmt`
328+
/// with `TypeNS` as namespace.
329+
///
330+
/// We need a separate function here because we won't suggest for a path with single segment
331+
/// and we won't change `SourcePath` api `is_expected` to match `Type` with `DefKind::Mod`
332+
pub(crate) fn smart_resolve_partial_mod_path_errors(
333+
&mut self,
334+
prefix_path: &[Segment],
335+
path: &[Segment],
336+
) -> Vec<ImportSuggestion> {
337+
if path.len() <= 1 {
338+
return Vec::new();
339+
}
340+
let ident = prefix_path.last().unwrap().ident;
341+
self.r.lookup_import_candidates(
342+
ident,
343+
Namespace::TypeNS,
344+
&self.parent_scope,
345+
&|res: Res| matches!(res, Res::Def(DefKind::Mod, _)),
346+
)
347+
}
348+
321349
/// Handles error reporting for `smart_resolve_path_fragment` function.
322350
/// Creates base error and amends it with one short label and possibly some longer helps/notes.
323351
pub(crate) fn smart_resolve_report_errors(

tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ LL | let _: u8 = ::core::default::Default();
1313
| ^^^^ maybe a missing crate `core`?
1414
|
1515
= help: consider adding `extern crate core` to use the `core` crate
16+
help: consider importing this module
17+
|
18+
LL + use std::default;
19+
|
20+
help: if you import `default`, refer to it directly
21+
|
22+
LL - let _: u8 = ::core::default::Default();
23+
LL + let _: u8 = default::Default();
24+
|
1625

1726
error: aborting due to 2 previous errors
1827

tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,25 @@ LL | fn f() { my_core::mem::drop(0); }
2424
LL | a!();
2525
| ---- in this macro invocation
2626
|
27+
= help: consider importing this module:
28+
my_core::mem
2729
= note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info)
2830

2931
error[E0433]: failed to resolve: use of undeclared crate or module `my_core`
3032
--> $DIR/extern-prelude-from-opaque-fail.rs:24:14
3133
|
3234
LL | fn f() { my_core::mem::drop(0); }
3335
| ^^^^^^^ use of undeclared crate or module `my_core`
36+
|
37+
help: consider importing this module
38+
|
39+
LL + use my_core::mem;
40+
|
41+
help: if you import `mem`, refer to it directly
42+
|
43+
LL - fn f() { my_core::mem::drop(0); }
44+
LL + fn f() { mem::drop(0); }
45+
|
3446

3547
error: aborting due to 4 previous errors
3648

tests/ui/macros/builtin-prelude-no-accidents.stderr

+24-8
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,37 @@ error[E0433]: failed to resolve: use of undeclared crate or module `env`
33
|
44
LL | env::current_dir;
55
| ^^^ use of undeclared crate or module `env`
6-
7-
error[E0433]: failed to resolve: use of undeclared crate or module `vec`
8-
--> $DIR/builtin-prelude-no-accidents.rs:7:14
96
|
10-
LL | type B = vec::Vec<u8>;
11-
| ^^^
12-
| |
13-
| use of undeclared crate or module `vec`
14-
| help: a struct with a similar name exists (notice the capitalization): `Vec`
7+
help: consider importing this module
8+
|
9+
LL + use std::env;
10+
|
1511

1612
error[E0433]: failed to resolve: use of undeclared crate or module `panic`
1713
--> $DIR/builtin-prelude-no-accidents.rs:6:14
1814
|
1915
LL | type A = panic::PanicInfo;
2016
| ^^^^^ use of undeclared crate or module `panic`
17+
|
18+
help: consider importing this module
19+
|
20+
LL + use std::panic;
21+
|
22+
23+
error[E0433]: failed to resolve: use of undeclared crate or module `vec`
24+
--> $DIR/builtin-prelude-no-accidents.rs:7:14
25+
|
26+
LL | type B = vec::Vec<u8>;
27+
| ^^^ use of undeclared crate or module `vec`
28+
|
29+
help: a struct with a similar name exists
30+
|
31+
LL | type B = Vec::Vec<u8>;
32+
| ~~~
33+
help: consider importing this module
34+
|
35+
LL + use std::vec;
36+
|
2137

2238
error: aborting due to 3 previous errors
2339

tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr

+15-5
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@ error: unexpected `const` parameter declaration
2121
LL | path::path::Struct::<const N: usize>()
2222
| ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration
2323

24+
error[E0412]: cannot find type `T` in this scope
25+
--> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15
26+
|
27+
LL | fn banana(a: <T<const N: usize>>::BAR) {}
28+
| ^ not found in this scope
29+
2430
error[E0433]: failed to resolve: use of undeclared crate or module `path`
2531
--> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5
2632
|
2733
LL | path::path::Struct::<const N: usize>()
2834
| ^^^^ use of undeclared crate or module `path`
29-
30-
error[E0412]: cannot find type `T` in this scope
31-
--> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15
3235
|
33-
LL | fn banana(a: <T<const N: usize>>::BAR) {}
34-
| ^ not found in this scope
36+
help: consider importing this module
37+
|
38+
LL + use std::path;
39+
|
40+
help: if you import `path`, refer to it directly
41+
|
42+
LL - path::path::Struct::<const N: usize>()
43+
LL + path::Struct::<const N: usize>()
44+
|
3545

3646
error[E0308]: mismatched types
3747
--> $DIR/const-param-decl-on-type-instead-of-impl.rs:5:17

tests/ui/resolve/export-fully-qualified.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo`
33
|
44
LL | pub fn bar() { foo::baz(); }
55
| ^^^ use of undeclared crate or module `foo`
6+
|
7+
help: consider importing this module
8+
|
9+
LL + use foo;
10+
|
611

712
error: aborting due to previous error
813

tests/ui/suggestions/crate-or-module-typo.stderr

+21-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ help: there is a crate or module with a similar name
2020
LL | use bar::bar;
2121
| ~~~
2222

23+
error[E0433]: failed to resolve: use of undeclared crate or module `bar`
24+
--> $DIR/crate-or-module-typo.rs:6:20
25+
|
26+
LL | pub fn bar() { bar::baz(); }
27+
| ^^^ use of undeclared crate or module `bar`
28+
|
29+
help: consider importing this module
30+
|
31+
LL + use crate::bar;
32+
|
33+
2334
error[E0433]: failed to resolve: use of undeclared crate or module `st`
2435
--> $DIR/crate-or-module-typo.rs:14:10
2536
|
@@ -30,12 +41,17 @@ help: there is a crate or module with a similar name
3041
|
3142
LL | bar: std::cell::Cell<bool>
3243
| ~~~
33-
34-
error[E0433]: failed to resolve: use of undeclared crate or module `bar`
35-
--> $DIR/crate-or-module-typo.rs:6:20
44+
help: consider importing one of these items
45+
|
46+
LL + use core::cell;
47+
|
48+
LL + use std::cell;
49+
|
50+
help: if you import `cell`, refer to it directly
51+
|
52+
LL - bar: st::cell::Cell<bool>
53+
LL + bar: cell::Cell<bool>
3654
|
37-
LL | pub fn bar() { bar::baz(); }
38-
| ^^^ use of undeclared crate or module `bar`
3955

4056
error: aborting due to 4 previous errors
4157

0 commit comments

Comments
 (0)