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
60 changes: 44 additions & 16 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
"too many leading `super` keywords".to_string(),
"there are too many leading `super` keywords".to_string(),
None,
None,
)
},
);
Expand Down Expand Up @@ -1889,7 +1890,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
"can only be used in path start position".to_string(),
)
};
(message, label, None)
(message, label, None, None)
},
);
}
Expand Down Expand Up @@ -2000,10 +2001,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module_had_parse_errors,
module,
|| {
let import_inherent_item_error_flag =
self.tcx.features().import_trait_associated_functions()
&& matches!(
res,
Res::Def(
DefKind::Struct
| DefKind::Enum
| DefKind::Union
| DefKind::ForeignTy,
_
)
);
// Show a different error message for items that can have associated items.
let label = format!(
"`{ident}` is {} {}, not a module",
"`{ident}` is {} {}, not a module{}",
res.article(),
res.descr()
res.descr(),
if import_inherent_item_error_flag {
" or a trait"
} else {
""
}
);
let scope = match &path[..segment_idx] {
[.., prev] => {
Expand All @@ -2018,7 +2037,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// FIXME: reword, as the reason we expected a module is because of
// the following path segment.
let message = format!("cannot find module `{ident}` in {scope}");
(message, label, None)
let note = if import_inherent_item_error_flag {
Some(
"cannot import inherent associated items, only trait associated items".to_string(),
)
} else {
None
};
(message, label, None, note)
},
);
}
Expand All @@ -2043,18 +2069,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module_had_parse_errors,
module,
|| {
this.get_mut().report_path_resolution_error(
path,
opt_ns,
parent_scope,
ribs,
ignore_decl,
ignore_import,
module,
segment_idx,
ident,
diag_metadata,
)
let (message, label, suggestion) =
this.get_mut().report_path_resolution_error(
path,
opt_ns,
parent_scope,
ribs,
ignore_decl,
ignore_import,
module,
segment_idx,
ident,
diag_metadata,
);
(message, label, suggestion, None)
},
);
}
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module,
error_implied_by_parse_error: _,
message,
note: _,
} => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
Expand All @@ -1069,6 +1070,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
suggestion,
module,
segment_name,
note,
..
} => {
if no_ambiguity {
Expand Down Expand Up @@ -1097,7 +1099,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => UnresolvedImportError {
span,
label: Some(label),
note: None,
note,
suggestion,
candidates: None,
segment: Some(segment_name),
Expand Down Expand Up @@ -1325,6 +1327,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
_ => (lev_suggestion, None),
};

// If importing of trait asscoiated items is enabled, an also find an
// `Enum`, then note that inherent associated items cannot be imported.
let note = if self.tcx.features().import_trait_associated_functions()
&& let PathResult::Module(ModuleOrUniformRoot::Module(m)) = path_res
&& let Some(Res::Def(DefKind::Enum, _)) = m.res()
{
note.or(Some(
"cannot import inherent associated items, only trait associated items"
.to_string(),
))
} else {
note
};

let label = match module {
ModuleOrUniformRoot::Module(module) => {
let module_str = module_to_string(module);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4891,6 +4891,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
segment_name,
error_implied_by_parse_error: _,
message,
note: _,
} => {
return Err(respan(
span,
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ enum PathResult<'ra> {
segment_name: Symbol,
error_implied_by_parse_error: bool,
message: String,
note: Option<String>,
},
}

Expand All @@ -488,13 +489,18 @@ impl<'ra> PathResult<'ra> {
finalize: bool,
error_implied_by_parse_error: bool,
module: Option<ModuleOrUniformRoot<'ra>>,
label_and_suggestion: impl FnOnce() -> (String, String, Option<Suggestion>),
label_and_suggestion_and_note: impl FnOnce() -> (
String,
String,
Option<Suggestion>,
Option<String>,
),
) -> PathResult<'ra> {
let (message, label, suggestion) = if finalize {
label_and_suggestion()
let (message, label, suggestion, note) = if finalize {
label_and_suggestion_and_note()
} else {
// FIXME: this output isn't actually present in the test suite.
(format!("cannot find `{ident}` in this scope"), String::new(), None)
(format!("cannot find `{ident}` in this scope"), String::new(), None, None)
};
PathResult::Failed {
span: ident.span,
Expand All @@ -505,6 +511,7 @@ impl<'ra> PathResult<'ra> {
module,
error_implied_by_parse_error,
message,
note,
}
}
}
Expand Down
68 changes: 68 additions & 0 deletions tests/ui/imports/import-inherent-148009.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Check that when the feature `import_trait_associated_functions` is enabled,
//! and one trys to import inherent associated items, the error message is
//! updated to reflect that only trait associated items can be imported.
//!
//! Regression test for <https://github.com/rust-lang/rust/issues/148009>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you have to add further annotations to actually test the label? Something like //~| NOTE cannot import inherent associated items, only trait associated items IIRC?

Copy link
Contributor Author

@CoCo-Japan-pan CoCo-Japan-pan Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a note NOTE cannot import inherent associated items, only trait associated items in fae6a31


//@ check-fail

#![feature(import_trait_associated_functions, extern_types)]

pub struct TestStruct;

impl TestStruct {
pub fn m1() {}
pub const C1: usize = 0;
}

pub use self::TestStruct::{C1, m1};
//~^ ERROR unresolved import `self::TestStruct` [E0432]
//~| NOTE `TestStruct` is a struct, not a module or a trait
//~| NOTE cannot import inherent associated items, only trait associated items

pub union TestUnion {
pub f: f32,
pub i: i32,
}

impl TestUnion {
pub fn m2() {}
pub const C2: usize = 0;
}

pub use self::TestUnion::{C2, m2};
//~^ ERROR unresolved import `self::TestUnion` [E0432]
//~| NOTE `TestUnion` is a union, not a module or a trait
//~| NOTE cannot import inherent associated items, only trait associated items

pub enum TestEnum {
V1,
V2,
}

impl TestEnum {
pub fn m3() {}
pub const C3: usize = 0;
}

pub use self::TestEnum::{C3, m3};
//~^ ERROR unresolved imports `self::TestEnum::C3`, `self::TestEnum::m3` [E0432]
//~| NOTE no `m3` in `TestEnum`
//~| NOTE no `C3` in `TestEnum`
//~| NOTE cannot import inherent associated items, only trait associated items

extern "C" {
pub type TestForeignTy;
}

impl TestForeignTy {
pub fn m4() {}
pub const C4: usize = 0;
}

pub use self::TestForeignTy::{C4, m4};
//~^ ERROR unresolved import `self::TestForeignTy` [E0432]
//~| NOTE `TestForeignTy` is a foreign type, not a module or a trait
//~| NOTE cannot import inherent associated items, only trait associated items

fn main() {}
37 changes: 37 additions & 0 deletions tests/ui/imports/import-inherent-148009.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
error[E0432]: unresolved import `self::TestStruct`
--> $DIR/import-inherent-148009.rs:18:15
|
LL | pub use self::TestStruct::{C1, m1};
| ^^^^^^^^^^ `TestStruct` is a struct, not a module or a trait
|
= note: cannot import inherent associated items, only trait associated items

error[E0432]: unresolved import `self::TestUnion`
--> $DIR/import-inherent-148009.rs:33:15
|
LL | pub use self::TestUnion::{C2, m2};
| ^^^^^^^^^ `TestUnion` is a union, not a module or a trait
|
= note: cannot import inherent associated items, only trait associated items

error[E0432]: unresolved imports `self::TestEnum::C3`, `self::TestEnum::m3`
--> $DIR/import-inherent-148009.rs:48:26
|
LL | pub use self::TestEnum::{C3, m3};
| ^^ ^^ no `m3` in `TestEnum`
| |
| no `C3` in `TestEnum`
|
= note: cannot import inherent associated items, only trait associated items

error[E0432]: unresolved import `self::TestForeignTy`
--> $DIR/import-inherent-148009.rs:63:15
|
LL | pub use self::TestForeignTy::{C4, m4};
| ^^^^^^^^^^^^^ `TestForeignTy` is a foreign type, not a module or a trait
|
= note: cannot import inherent associated items, only trait associated items

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0432`.
Loading