Skip to content

Commit 0b7ff8d

Browse files
committed
resolve: Support imports of associated types and glob imports from traits
1 parent 7d49ae9 commit 0b7ff8d

20 files changed

+127
-99
lines changed

compiler/rustc_error_codes/src/error_codes/E0253.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
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

46
Erroneous code example:
57

6-
```compile_fail,E0253
8+
```
9+
#![feature(import_trait_associated_functions)]
10+
711
mod foo {
812
pub trait MyTrait {
913
type SomeType;

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 14 additions & 2 deletions
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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,6 @@ resolve_invalid_asm_sym =
218218
.label = is a local variable
219219
.help = `sym` operands must refer to either a function or a static
220220
221-
resolve_is_not_directly_importable =
222-
`{$target}` is not directly importable
223-
.label = cannot be imported directly
224-
225221
resolve_is_private =
226222
{$ident_descr} `{$ident}` is private
227223
.label = private {$ident_descr}
@@ -231,9 +227,6 @@ resolve_item_was_behind_feature =
231227
232228
resolve_item_was_cfg_out = the item is gated here
233229
234-
resolve_items_in_traits_are_not_importable =
235-
items in traits are not importable
236-
237230
resolve_label_with_similar_name_reachable =
238231
a label with a similar name is reachable
239232

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 3 additions & 5 deletions
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

Lines changed: 0 additions & 16 deletions
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

Lines changed: 23 additions & 20 deletions
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

Lines changed: 2 additions & 8 deletions
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

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/ui/error-codes/E0253.stderr

Lines changed: 0 additions & 9 deletions
This file was deleted.

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

Lines changed: 3 additions & 0 deletions
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() {}

0 commit comments

Comments
 (0)