Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve: Support imports of associated types and glob imports from traits #138712

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
6 changes: 5 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0253.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#### Note: this error code is no longer emitted by the compiler.

Attempt was made to import an unimportable type. This can happen when trying
to import a type from a trait.

Erroneous code example:

```compile_fail,E0253
```
#![feature(import_trait_associated_functions)]

mod foo {
pub trait MyTrait {
type SomeType;
Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2177,7 +2177,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}
Res::Def(DefKind::AssocTy, def_id) => {
debug_assert!(path.segments.len() >= 2);
if path.segments.len() < 2 {
let guar = self
.dcx()
.struct_span_err(span, "cannot infer type, type annotations needed")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

#138711 is an issue for reporting some proper error here instead of this stub.

.emit();
return Ty::new_error(tcx, guar);
}
let _ = self.prohibit_generic_args(
path.segments[..path.segments.len() - 2].iter(),
GenericsArgsErrExtend::None,
Expand Down Expand Up @@ -2394,7 +2400,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
}
Res::Def(DefKind::AssocConst, did) => {
debug_assert!(path.segments.len() >= 2);
if path.segments.len() < 2 {
let guar = self
.dcx()
.struct_span_err(span, "cannot infer type, type annotations needed")
Copy link
Contributor

@fbstj fbstj Mar 19, 2025

Choose a reason for hiding this comment

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

Suggested change
.struct_span_err(span, "cannot infer type, type annotations needed")
.struct_span_err(span, "cannot infer value from uninitialized type")

from what I can tell of tests/ui/use/import_trait_associated_item_bad.rs the error isn't really type related?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error is copypasted from the non-min_generic_const_args case, see #138711.
(It's the Self type that cannot be inferred here.)

.emit();
return Const::new_error(tcx, guar);
}
let _ = self.prohibit_generic_args(
path.segments[..path.segments.len() - 2].iter(),
GenericsArgsErrExtend::None,
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,6 @@ resolve_invalid_asm_sym =
.label = is a local variable
.help = `sym` operands must refer to either a function or a static

resolve_is_not_directly_importable =
`{$target}` is not directly importable
.label = cannot be imported directly

resolve_is_private =
{$ident_descr} `{$ident}` is private
.label = private {$ident_descr}
Expand All @@ -231,9 +227,6 @@ resolve_item_was_behind_feature =

resolve_item_was_cfg_out = the item is gated here

resolve_items_in_traits_are_not_importable =
items in traits are not importable

resolve_label_with_similar_name_reachable =
a label with a similar name is reachable

Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1181,11 +1181,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} {
let in_module_is_extern = !in_module.def_id().is_local();
in_module.for_each_child(self, |this, ident, ns, name_binding| {
// avoid non-importable candidates
if !name_binding.is_importable()
// FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable
|| name_binding.is_assoc_const_or_fn()
&& !this.tcx.features().import_trait_associated_functions()
// Avoid non-importable candidates.
if name_binding.is_assoc_item()
&& !this.tcx.features().import_trait_associated_functions()
{
return;
}
Expand Down
16 changes: 0 additions & 16 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,22 +781,6 @@ pub(crate) struct CannotGlobImportAllCrates {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(resolve_items_in_traits_are_not_importable)]
pub(crate) struct ItemsInTraitsAreNotImportable {
#[primary_span]
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(resolve_is_not_directly_importable, code = E0253)]
pub(crate) struct IsNotDirectlyImportable {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) target: Ident,
}

#[derive(Subdiagnostic)]
#[suggestion(
resolve_unexpected_res_change_ty_to_const_param_sugg,
Expand Down
43 changes: 23 additions & 20 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
use crate::errors::{
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
ItemsInTraitsAreNotImportable,
ConsiderAddingMacroExport, ConsiderMarkingAsPub,
};
use crate::{
AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
Expand Down Expand Up @@ -835,11 +834,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

let parent = import.parent_scope.module;
match source_bindings[ns].get() {
Err(Undetermined) => indeterminate_count += 1,
// Don't update the resolution, because it was never added.
Err(Determined) if target.name == kw::Underscore => {}
Ok(binding) if binding.is_importable() => {
if binding.is_assoc_const_or_fn()
Ok(binding) => {
if binding.is_assoc_item()
&& !this.tcx.features().import_trait_associated_functions()
{
feature_err(
Expand All @@ -850,21 +846,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)
.emit();
}

let imported_binding = this.import(binding, import);
target_bindings[ns].set(Some(imported_binding));
this.define(parent, target, ns, imported_binding);
}
source_binding @ (Ok(..) | Err(Determined)) => {
if source_binding.is_ok() {
this.dcx()
.create_err(IsNotDirectlyImportable { span: import.span, target })
.emit();
Err(Determined) => {
// Don't update the resolution for underscores, because it was never added.
if target.name != kw::Underscore {
let key = BindingKey::new(target, ns);
this.update_resolution(parent, key, false, |_, resolution| {
resolution.single_imports.remove(&import);
});
}
let key = BindingKey::new(target, ns);
this.update_resolution(parent, key, false, |_, resolution| {
resolution.single_imports.remove(&import);
});
}
Err(Undetermined) => indeterminate_count += 1,
}
}
});
Expand Down Expand Up @@ -1428,10 +1424,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return;
};

if module.is_trait() {
self.dcx().emit_err(ItemsInTraitsAreNotImportable { span: import.span });
return;
} else if module == import.parent_scope.module {
if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
feature_err(
self.tcx.sess,
sym::import_trait_associated_functions,
import.span,
"`use` associated items of traits is unstable",
)
.emit();
}

if module == import.parent_scope.module {
return;
} else if is_prelude {
self.prelude = Some(module);
Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,14 +947,8 @@ impl<'ra> NameBindingData<'ra> {
}
}

fn is_importable(&self) -> bool {
!matches!(self.res(), Res::Def(DefKind::AssocTy, _))
}

// FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless
// the feature `import_trait_associated_functions` is enable
fn is_assoc_const_or_fn(&self) -> bool {
matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
fn is_assoc_item(&self) -> bool {
matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _))
}

fn macro_kind(&self) -> Option<MacroKind> {
Expand Down
10 changes: 0 additions & 10 deletions tests/ui/error-codes/E0253.rs

This file was deleted.

9 changes: 0 additions & 9 deletions tests/ui/error-codes/E0253.stderr

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,7 @@ fn f() {
let t: Option<S> = DEFAULT;
}

trait Glob {}
use Glob::*; //~ ERROR `use` associated items of traits is unstable

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ LL | use super::A::{self, DEFAULT, new};
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 5 previous errors
error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:64:5
|
LL | use Glob::*;
| ^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0658`.
3 changes: 0 additions & 3 deletions tests/ui/imports/issue-30560.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@ use Alias::*; //~ ERROR unresolved import `Alias` [E0432]

use std::io::Result::*; //~ ERROR unresolved import `std::io::Result` [E0432]

trait T {}
use T::*; //~ ERROR items in traits are not importable

fn main() {}
8 changes: 1 addition & 7 deletions tests/ui/imports/issue-30560.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
error: items in traits are not importable
--> $DIR/issue-30560.rs:7:5
|
LL | use T::*;
| ^^^^

error[E0432]: unresolved import `Alias`
--> $DIR/issue-30560.rs:2:5
|
Expand All @@ -16,6 +10,6 @@ error[E0432]: unresolved import `std::io::Result`
LL | use std::io::Result::*;
| ^^^^^^ `Result` is a type alias, not a module

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0432`.
16 changes: 16 additions & 0 deletions tests/ui/use/import_trait_associated_item_bad.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![feature(import_trait_associated_functions)]
#![feature(min_generic_const_args)]
#![allow(incomplete_features)]

trait Trait {
type AssocTy;
const CONST: usize;
}

use Trait::AssocTy;
type Alias1 = AssocTy; //~ ERROR cannot infer type, type annotations needed

use Trait::CONST;
type Alias2 = [u8; CONST]; //~ ERROR cannot infer type, type annotations needed

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/use/import_trait_associated_item_bad.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: cannot infer type, type annotations needed
--> $DIR/import_trait_associated_item_bad.rs:11:15
|
LL | type Alias1 = AssocTy;
| ^^^^^^^

error: cannot infer type, type annotations needed
--> $DIR/import_trait_associated_item_bad.rs:14:20
|
LL | type Alias2 = [u8; CONST];
| ^^^^^

error: aborting due to 2 previous errors

17 changes: 17 additions & 0 deletions tests/ui/use/import_trait_associated_item_glob.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ check-pass

#![feature(import_trait_associated_functions)]

trait Trait: Default {
fn f() -> Self { Default::default() }
fn g() -> Self { Default::default() }
}

impl Trait for u8 {}

use Trait::*;

fn main() {
let _: u8 = f();
let _: u8 = g();
}
2 changes: 1 addition & 1 deletion tests/ui/use/use-from-trait-xc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use use_from_trait_xc::Trait::foo;
//~^ ERROR `use` associated items of traits is unstable [E0658]

use use_from_trait_xc::Trait::Assoc;
//~^ ERROR `Assoc` is not directly importable
//~^ ERROR `use` associated items of traits is unstable [E0658]

use use_from_trait_xc::Trait::CONST;
//~^ ERROR `use` associated items of traits is unstable [E0658]
Expand Down
12 changes: 8 additions & 4 deletions tests/ui/use/use-from-trait-xc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ LL | use use_from_trait_xc::Trait::foo;
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0253]: `Assoc` is not directly importable
error[E0658]: `use` associated items of traits is unstable
--> $DIR/use-from-trait-xc.rs:8:5
|
LL | use use_from_trait_xc::Trait::Assoc;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/use-from-trait-xc.rs:11:5
Expand Down Expand Up @@ -74,5 +78,5 @@ LL | struct Foo;

error: aborting due to 9 previous errors

Some errors have detailed explanations: E0253, E0432, E0603, E0658.
For more information about an error, try `rustc --explain E0253`.
Some errors have detailed explanations: E0432, E0603, E0658.
For more information about an error, try `rustc --explain E0432`.
2 changes: 1 addition & 1 deletion tests/ui/use/use-from-trait.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
use Trait::Assoc; //~ ERROR `Assoc` is not directly importable
use Trait::Assoc; //~ ERROR `use` associated items of traits is unstable [E0658]
use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658]

use Foo::new; //~ ERROR unresolved import `Foo` [E0432]
Expand Down
12 changes: 8 additions & 4 deletions tests/ui/use/use-from-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ LL | use Trait::foo;
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0253]: `Assoc` is not directly importable
error[E0658]: `use` associated items of traits is unstable
--> $DIR/use-from-trait.rs:2:5
|
LL | use Trait::Assoc;
| ^^^^^^^^^^^^ cannot be imported directly
| ^^^^^^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/use-from-trait.rs:3:5
Expand All @@ -38,5 +42,5 @@ LL | use Foo::C2;

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0253, E0432, E0658.
For more information about an error, try `rustc --explain E0253`.
Some errors have detailed explanations: E0432, E0658.
For more information about an error, try `rustc --explain E0432`.
Loading