Skip to content

Commit 30fb97f

Browse files
committed
resolve: Support imports of associated types and glob imports from traits
1 parent c4b38a5 commit 30fb97f

20 files changed

+124
-98
lines changed

compiler/rustc_error_codes/src/error_codes/E0253.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
Attempt was made to import an unimportable type. This can happen when trying
24
to import a type from a trait.
35

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21772177
}
21782178
}
21792179
Res::Def(DefKind::AssocTy, def_id) => {
2180-
debug_assert!(path.segments.len() >= 2);
2180+
if path.segments.len() < 2 {
2181+
let guar = self
2182+
.dcx()
2183+
.struct_span_err(span, "cannot infer type, type annotations needed")
2184+
.emit();
2185+
return Ty::new_error(tcx, guar);
2186+
}
21812187
let _ = self.prohibit_generic_args(
21822188
path.segments[..path.segments.len() - 2].iter(),
21832189
GenericsArgsErrExtend::None,
@@ -2394,7 +2400,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23942400
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
23952401
}
23962402
Res::Def(DefKind::AssocConst, did) => {
2397-
debug_assert!(path.segments.len() >= 2);
2403+
if path.segments.len() < 2 {
2404+
let guar = self
2405+
.dcx()
2406+
.struct_span_err(span, "cannot infer type, type annotations needed")
2407+
.emit();
2408+
return Const::new_error(tcx, guar);
2409+
}
23982410
let _ = self.prohibit_generic_args(
23992411
path.segments[..path.segments.len() - 2].iter(),
24002412
GenericsArgsErrExtend::None,

compiler/rustc_resolve/messages.ftl

-7
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,6 @@ resolve_invalid_asm_sym =
222222
.label = is a local variable
223223
.help = `sym` operands must refer to either a function or a static
224224
225-
resolve_is_not_directly_importable =
226-
`{$target}` is not directly importable
227-
.label = cannot be imported directly
228-
229225
resolve_is_private =
230226
{$ident_descr} `{$ident}` is private
231227
.label = private {$ident_descr}
@@ -235,9 +231,6 @@ resolve_item_was_behind_feature =
235231
236232
resolve_item_was_cfg_out = the item is gated here
237233
238-
resolve_items_in_traits_are_not_importable =
239-
items in traits are not importable
240-
241234
resolve_label_with_similar_name_reachable =
242235
a label with a similar name is reachable
243236

compiler/rustc_resolve/src/diagnostics.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1181,11 +1181,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11811181
} {
11821182
let in_module_is_extern = !in_module.def_id().is_local();
11831183
in_module.for_each_child(self, |this, ident, ns, name_binding| {
1184-
// avoid non-importable candidates
1185-
if !name_binding.is_importable()
1186-
// FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable
1187-
|| name_binding.is_assoc_const_or_fn()
1188-
&& !this.tcx.features().import_trait_associated_functions()
1184+
// Avoid non-importable candidates.
1185+
if name_binding.is_assoc_item()
1186+
&& !this.tcx.features().import_trait_associated_functions()
11891187
{
11901188
return;
11911189
}

compiler/rustc_resolve/src/errors.rs

-16
Original file line numberDiff line numberDiff line change
@@ -781,22 +781,6 @@ pub(crate) struct CannotGlobImportAllCrates {
781781
pub(crate) span: Span,
782782
}
783783

784-
#[derive(Diagnostic)]
785-
#[diag(resolve_items_in_traits_are_not_importable)]
786-
pub(crate) struct ItemsInTraitsAreNotImportable {
787-
#[primary_span]
788-
pub(crate) span: Span,
789-
}
790-
791-
#[derive(Diagnostic)]
792-
#[diag(resolve_is_not_directly_importable, code = E0253)]
793-
pub(crate) struct IsNotDirectlyImportable {
794-
#[primary_span]
795-
#[label]
796-
pub(crate) span: Span,
797-
pub(crate) target: Ident,
798-
}
799-
800784
#[derive(Subdiagnostic)]
801785
#[suggestion(
802786
resolve_unexpected_res_change_ty_to_const_param_sugg,

compiler/rustc_resolve/src/imports.rs

+23-20
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
3030
use crate::errors::{
3131
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
3232
CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
33-
ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
34-
ItemsInTraitsAreNotImportable,
33+
ConsiderAddingMacroExport, ConsiderMarkingAsPub,
3534
};
3635
use crate::{
3736
AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
@@ -835,11 +834,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
835834

836835
let parent = import.parent_scope.module;
837836
match source_bindings[ns].get() {
838-
Err(Undetermined) => indeterminate_count += 1,
839-
// Don't update the resolution, because it was never added.
840-
Err(Determined) if target.name == kw::Underscore => {}
841-
Ok(binding) if binding.is_importable() => {
842-
if binding.is_assoc_const_or_fn()
837+
Ok(binding) => {
838+
if binding.is_assoc_item()
843839
&& !this.tcx.features().import_trait_associated_functions()
844840
{
845841
feature_err(
@@ -850,21 +846,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
850846
)
851847
.emit();
852848
}
849+
853850
let imported_binding = this.import(binding, import);
854851
target_bindings[ns].set(Some(imported_binding));
855852
this.define(parent, target, ns, imported_binding);
856853
}
857-
source_binding @ (Ok(..) | Err(Determined)) => {
858-
if source_binding.is_ok() {
859-
this.dcx()
860-
.create_err(IsNotDirectlyImportable { span: import.span, target })
861-
.emit();
854+
Err(Determined) => {
855+
// Don't update the resolution for underscores, because it was never added.
856+
if target.name != kw::Underscore {
857+
let key = BindingKey::new(target, ns);
858+
this.update_resolution(parent, key, false, |_, resolution| {
859+
resolution.single_imports.remove(&import);
860+
});
862861
}
863-
let key = BindingKey::new(target, ns);
864-
this.update_resolution(parent, key, false, |_, resolution| {
865-
resolution.single_imports.remove(&import);
866-
});
867862
}
863+
Err(Undetermined) => indeterminate_count += 1,
868864
}
869865
}
870866
});
@@ -1428,10 +1424,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14281424
return;
14291425
};
14301426

1431-
if module.is_trait() {
1432-
self.dcx().emit_err(ItemsInTraitsAreNotImportable { span: import.span });
1433-
return;
1434-
} else if module == import.parent_scope.module {
1427+
if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
1428+
feature_err(
1429+
self.tcx.sess,
1430+
sym::import_trait_associated_functions,
1431+
import.span,
1432+
"`use` associated items of traits is unstable",
1433+
)
1434+
.emit();
1435+
}
1436+
1437+
if module == import.parent_scope.module {
14351438
return;
14361439
} else if is_prelude {
14371440
self.prelude = Some(module);

compiler/rustc_resolve/src/lib.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -947,14 +947,8 @@ impl<'ra> NameBindingData<'ra> {
947947
}
948948
}
949949

950-
fn is_importable(&self) -> bool {
951-
!matches!(self.res(), Res::Def(DefKind::AssocTy, _))
952-
}
953-
954-
// FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless
955-
// the feature `import_trait_associated_functions` is enable
956-
fn is_assoc_const_or_fn(&self) -> bool {
957-
matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
950+
fn is_assoc_item(&self) -> bool {
951+
matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _))
958952
}
959953

960954
fn macro_kind(&self) -> Option<MacroKind> {

tests/ui/error-codes/E0253.rs

-10
This file was deleted.

tests/ui/error-codes/E0253.stderr

-9
This file was deleted.

tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs

+3
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,7 @@ fn f() {
6060
let t: Option<S> = DEFAULT;
6161
}
6262

63+
trait Glob {}
64+
use Glob::*; //~ ERROR `use` associated items of traits is unstable
65+
6366
fn main() {}

tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr

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

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

5363
For more information about this error, try `rustc --explain E0658`.

tests/ui/imports/issue-30560.rs

-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,4 @@ use Alias::*; //~ ERROR unresolved import `Alias` [E0432]
33

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

6-
trait T {}
7-
use T::*; //~ ERROR items in traits are not importable
8-
96
fn main() {}

tests/ui/imports/issue-30560.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
error: items in traits are not importable
2-
--> $DIR/issue-30560.rs:7:5
3-
|
4-
LL | use T::*;
5-
| ^^^^
6-
71
error[E0432]: unresolved import `Alias`
82
--> $DIR/issue-30560.rs:2:5
93
|
@@ -16,6 +10,6 @@ error[E0432]: unresolved import `std::io::Result`
1610
LL | use std::io::Result::*;
1711
| ^^^^^^ `Result` is a type alias, not a module
1812

19-
error: aborting due to 3 previous errors
13+
error: aborting due to 2 previous errors
2014

2115
For more information about this error, try `rustc --explain E0432`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(import_trait_associated_functions)]
2+
#![feature(min_generic_const_args)]
3+
#![allow(incomplete_features)]
4+
5+
trait Trait {
6+
type AssocTy;
7+
const CONST: usize;
8+
}
9+
10+
use Trait::AssocTy;
11+
type Alias1 = AssocTy; //~ ERROR cannot infer type, type annotations needed
12+
13+
use Trait::CONST;
14+
type Alias2 = [u8; CONST]; //~ ERROR cannot infer type, type annotations needed
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: cannot infer type, type annotations needed
2+
--> $DIR/import_trait_associated_item_bad.rs:11:15
3+
|
4+
LL | type Alias1 = AssocTy;
5+
| ^^^^^^^
6+
7+
error: cannot infer type, type annotations needed
8+
--> $DIR/import_trait_associated_item_bad.rs:14:20
9+
|
10+
LL | type Alias2 = [u8; CONST];
11+
| ^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ check-pass
2+
3+
#![feature(import_trait_associated_functions)]
4+
5+
trait Trait: Default {
6+
fn f() -> Self { Default::default() }
7+
fn g() -> Self { Default::default() }
8+
}
9+
10+
impl Trait for u8 {}
11+
12+
use Trait::*;
13+
14+
fn main() {
15+
let _: u8 = f();
16+
let _: u8 = g();
17+
}

tests/ui/use/use-from-trait-xc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use use_from_trait_xc::Trait::foo;
66
//~^ ERROR `use` associated items of traits is unstable [E0658]
77

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

1111
use use_from_trait_xc::Trait::CONST;
1212
//~^ ERROR `use` associated items of traits is unstable [E0658]

tests/ui/use/use-from-trait-xc.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ LL | use use_from_trait_xc::Trait::foo;
88
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

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

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

7579
error: aborting due to 9 previous errors
7680

77-
Some errors have detailed explanations: E0253, E0432, E0603, E0658.
78-
For more information about an error, try `rustc --explain E0253`.
81+
Some errors have detailed explanations: E0432, E0603, E0658.
82+
For more information about an error, try `rustc --explain E0432`.

tests/ui/use/use-from-trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
2-
use Trait::Assoc; //~ ERROR `Assoc` is not directly importable
2+
use Trait::Assoc; //~ ERROR `use` associated items of traits is unstable [E0658]
33
use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658]
44

55
use Foo::new; //~ ERROR unresolved import `Foo` [E0432]

tests/ui/use/use-from-trait.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ LL | use Trait::foo;
88
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

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

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

3943
error: aborting due to 5 previous errors
4044

41-
Some errors have detailed explanations: E0253, E0432, E0658.
42-
For more information about an error, try `rustc --explain E0253`.
45+
Some errors have detailed explanations: E0432, E0658.
46+
For more information about an error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)