Skip to content

Commit 04dfc2b

Browse files
Rollup merge of #152611 - CoCo-Japan-pan:fix-148009, r=jackh726
Modify error message of importing inherent associated items when `#[feature(import_trait_associated_functions)]` is enabled Fixes #148009 This PR improves the diagnostic for importing inherent associated items from a struct or union when `#[feature(import_trait_associated_functions)]` (#134691) is enabled. Previously, this would result in a "not a module" error. This change provides a more specific error message clarifying that only trait associated items can be imported, while inherent associated items remain ineligible for import. Enums are currently excluded from this change because their variants are valid import targets and require distinct handling.
2 parents 93637f3 + fae6a31 commit 04dfc2b

6 files changed

Lines changed: 178 additions & 21 deletions

File tree

compiler/rustc_resolve/src/ident.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
17971797
"too many leading `super` keywords".to_string(),
17981798
"there are too many leading `super` keywords".to_string(),
17991799
None,
1800+
None,
18001801
)
18011802
},
18021803
);
@@ -1863,7 +1864,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18631864
"can only be used in path start position".to_string(),
18641865
)
18651866
};
1866-
(message, label, None)
1867+
(message, label, None, None)
18671868
},
18681869
);
18691870
}
@@ -1977,10 +1978,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19771978
module_had_parse_errors,
19781979
module,
19791980
|| {
1981+
let import_inherent_item_error_flag =
1982+
self.tcx.features().import_trait_associated_functions()
1983+
&& matches!(
1984+
res,
1985+
Res::Def(
1986+
DefKind::Struct
1987+
| DefKind::Enum
1988+
| DefKind::Union
1989+
| DefKind::ForeignTy,
1990+
_
1991+
)
1992+
);
1993+
// Show a different error message for items that can have associated items.
19801994
let label = format!(
1981-
"`{ident}` is {} {}, not a module",
1995+
"`{ident}` is {} {}, not a module{}",
19821996
res.article(),
1983-
res.descr()
1997+
res.descr(),
1998+
if import_inherent_item_error_flag {
1999+
" or a trait"
2000+
} else {
2001+
""
2002+
}
19842003
);
19852004
let scope = match &path[..segment_idx] {
19862005
[.., prev] => {
@@ -1995,7 +2014,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19952014
// FIXME: reword, as the reason we expected a module is because of
19962015
// the following path segment.
19972016
let message = format!("cannot find module `{ident}` in {scope}");
1998-
(message, label, None)
2017+
let note = if import_inherent_item_error_flag {
2018+
Some(
2019+
"cannot import inherent associated items, only trait associated items".to_string(),
2020+
)
2021+
} else {
2022+
None
2023+
};
2024+
(message, label, None, note)
19992025
},
20002026
);
20012027
}
@@ -2020,18 +2046,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20202046
module_had_parse_errors,
20212047
module,
20222048
|| {
2023-
this.get_mut().report_path_resolution_error(
2024-
path,
2025-
opt_ns,
2026-
parent_scope,
2027-
ribs,
2028-
ignore_decl,
2029-
ignore_import,
2030-
module,
2031-
segment_idx,
2032-
ident,
2033-
diag_metadata,
2034-
)
2049+
let (message, label, suggestion) =
2050+
this.get_mut().report_path_resolution_error(
2051+
path,
2052+
opt_ns,
2053+
parent_scope,
2054+
ribs,
2055+
ignore_decl,
2056+
ignore_import,
2057+
module,
2058+
segment_idx,
2059+
ident,
2060+
diag_metadata,
2061+
);
2062+
(message, label, suggestion, None)
20352063
},
20362064
);
20372065
}

compiler/rustc_resolve/src/imports.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11341134
module,
11351135
error_implied_by_parse_error: _,
11361136
message,
1137+
note: _,
11371138
} => {
11381139
if no_ambiguity {
11391140
if !self.issue_145575_hack_applied {
@@ -1159,6 +1160,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11591160
suggestion,
11601161
module,
11611162
segment_name,
1163+
note,
11621164
..
11631165
} => {
11641166
if no_ambiguity {
@@ -1190,7 +1192,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11901192
None => UnresolvedImportError {
11911193
span,
11921194
label: Some(label),
1193-
note: None,
1195+
note,
11941196
suggestion,
11951197
candidates: None,
11961198
segment: Some(segment_name),
@@ -1420,6 +1422,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14201422
_ => (lev_suggestion, None),
14211423
};
14221424

1425+
// If importing of trait asscoiated items is enabled, an also find an
1426+
// `Enum`, then note that inherent associated items cannot be imported.
1427+
let note = if self.tcx.features().import_trait_associated_functions()
1428+
&& let PathResult::Module(ModuleOrUniformRoot::Module(m)) = path_res
1429+
&& let Some(Res::Def(DefKind::Enum, _)) = m.res()
1430+
{
1431+
note.or(Some(
1432+
"cannot import inherent associated items, only trait associated items"
1433+
.to_string(),
1434+
))
1435+
} else {
1436+
note
1437+
};
1438+
14231439
let label = match module {
14241440
ModuleOrUniformRoot::Module(module) => {
14251441
let module_str = module_to_string(module);

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4979,6 +4979,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
49794979
segment_name,
49804980
error_implied_by_parse_error: _,
49814981
message,
4982+
note: _,
49824983
} => {
49834984
return Err(respan(
49844985
span,

compiler/rustc_resolve/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ enum PathResult<'ra> {
481481
segment_name: Symbol,
482482
error_implied_by_parse_error: bool,
483483
message: String,
484+
note: Option<String>,
484485
},
485486
}
486487

@@ -491,13 +492,18 @@ impl<'ra> PathResult<'ra> {
491492
finalize: bool,
492493
error_implied_by_parse_error: bool,
493494
module: Option<ModuleOrUniformRoot<'ra>>,
494-
label_and_suggestion: impl FnOnce() -> (String, String, Option<Suggestion>),
495+
label_and_suggestion_and_note: impl FnOnce() -> (
496+
String,
497+
String,
498+
Option<Suggestion>,
499+
Option<String>,
500+
),
495501
) -> PathResult<'ra> {
496-
let (message, label, suggestion) = if finalize {
497-
label_and_suggestion()
502+
let (message, label, suggestion, note) = if finalize {
503+
label_and_suggestion_and_note()
498504
} else {
499505
// FIXME: this output isn't actually present in the test suite.
500-
(format!("cannot find `{ident}` in this scope"), String::new(), None)
506+
(format!("cannot find `{ident}` in this scope"), String::new(), None, None)
501507
};
502508
PathResult::Failed {
503509
span: ident.span,
@@ -508,6 +514,7 @@ impl<'ra> PathResult<'ra> {
508514
module,
509515
error_implied_by_parse_error,
510516
message,
517+
note,
511518
}
512519
}
513520
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//! Check that when the feature `import_trait_associated_functions` is enabled,
2+
//! and one trys to import inherent associated items, the error message is
3+
//! updated to reflect that only trait associated items can be imported.
4+
//!
5+
//! Regression test for <https://github.com/rust-lang/rust/issues/148009>.
6+
7+
//@ check-fail
8+
9+
#![feature(import_trait_associated_functions, extern_types)]
10+
11+
pub struct TestStruct;
12+
13+
impl TestStruct {
14+
pub fn m1() {}
15+
pub const C1: usize = 0;
16+
}
17+
18+
pub use self::TestStruct::{C1, m1};
19+
//~^ ERROR unresolved import `self::TestStruct` [E0432]
20+
//~| NOTE `TestStruct` is a struct, not a module or a trait
21+
//~| NOTE cannot import inherent associated items, only trait associated items
22+
23+
pub union TestUnion {
24+
pub f: f32,
25+
pub i: i32,
26+
}
27+
28+
impl TestUnion {
29+
pub fn m2() {}
30+
pub const C2: usize = 0;
31+
}
32+
33+
pub use self::TestUnion::{C2, m2};
34+
//~^ ERROR unresolved import `self::TestUnion` [E0432]
35+
//~| NOTE `TestUnion` is a union, not a module or a trait
36+
//~| NOTE cannot import inherent associated items, only trait associated items
37+
38+
pub enum TestEnum {
39+
V1,
40+
V2,
41+
}
42+
43+
impl TestEnum {
44+
pub fn m3() {}
45+
pub const C3: usize = 0;
46+
}
47+
48+
pub use self::TestEnum::{C3, m3};
49+
//~^ ERROR unresolved imports `self::TestEnum::C3`, `self::TestEnum::m3` [E0432]
50+
//~| NOTE no `m3` in `TestEnum`
51+
//~| NOTE no `C3` in `TestEnum`
52+
//~| NOTE cannot import inherent associated items, only trait associated items
53+
54+
extern "C" {
55+
pub type TestForeignTy;
56+
}
57+
58+
impl TestForeignTy {
59+
pub fn m4() {}
60+
pub const C4: usize = 0;
61+
}
62+
63+
pub use self::TestForeignTy::{C4, m4};
64+
//~^ ERROR unresolved import `self::TestForeignTy` [E0432]
65+
//~| NOTE `TestForeignTy` is a foreign type, not a module or a trait
66+
//~| NOTE cannot import inherent associated items, only trait associated items
67+
68+
fn main() {}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error[E0432]: unresolved import `self::TestStruct`
2+
--> $DIR/import-inherent-148009.rs:18:15
3+
|
4+
LL | pub use self::TestStruct::{C1, m1};
5+
| ^^^^^^^^^^ `TestStruct` is a struct, not a module or a trait
6+
|
7+
= note: cannot import inherent associated items, only trait associated items
8+
9+
error[E0432]: unresolved import `self::TestUnion`
10+
--> $DIR/import-inherent-148009.rs:33:15
11+
|
12+
LL | pub use self::TestUnion::{C2, m2};
13+
| ^^^^^^^^^ `TestUnion` is a union, not a module or a trait
14+
|
15+
= note: cannot import inherent associated items, only trait associated items
16+
17+
error[E0432]: unresolved imports `self::TestEnum::C3`, `self::TestEnum::m3`
18+
--> $DIR/import-inherent-148009.rs:48:26
19+
|
20+
LL | pub use self::TestEnum::{C3, m3};
21+
| ^^ ^^ no `m3` in `TestEnum`
22+
| |
23+
| no `C3` in `TestEnum`
24+
|
25+
= note: cannot import inherent associated items, only trait associated items
26+
27+
error[E0432]: unresolved import `self::TestForeignTy`
28+
--> $DIR/import-inherent-148009.rs:63:15
29+
|
30+
LL | pub use self::TestForeignTy::{C4, m4};
31+
| ^^^^^^^^^^^^^ `TestForeignTy` is a foreign type, not a module or a trait
32+
|
33+
= note: cannot import inherent associated items, only trait associated items
34+
35+
error: aborting due to 4 previous errors
36+
37+
For more information about this error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)