From 3eee3dad5c8aa36a88d6ed2e927c53f2ba174819 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Wed, 19 Mar 2025 16:11:45 +0300
Subject: [PATCH] resolve: Support imports of associated types and glob imports
 from traits

---
 .../src/error_codes/E0253.md                  |  6 ++-
 .../src/hir_ty_lowering/mod.rs                | 34 +++++++------
 compiler/rustc_resolve/messages.ftl           |  7 ---
 compiler/rustc_resolve/src/diagnostics.rs     |  8 ++-
 compiler/rustc_resolve/src/errors.rs          | 16 ------
 compiler/rustc_resolve/src/imports.rs         | 43 ++++++++--------
 compiler/rustc_resolve/src/lib.rs             | 10 +---
 tests/ui/error-codes/E0253.rs                 | 10 ----
 tests/ui/error-codes/E0253.stderr             |  9 ----
 ...-gate-import-trait-associated-functions.rs |  3 ++
 ...e-import-trait-associated-functions.stderr | 12 ++++-
 tests/ui/imports/issue-30560.rs               |  3 --
 tests/ui/imports/issue-30560.stderr           |  8 +--
 .../use/import_trait_associated_item_bad.rs   | 18 +++++++
 .../import_trait_associated_item_bad.stderr   | 49 +++++++++++++++++++
 .../use/import_trait_associated_item_glob.rs  | 17 +++++++
 tests/ui/use/use-from-trait-xc.rs             |  2 +-
 tests/ui/use/use-from-trait-xc.stderr         | 12 +++--
 tests/ui/use/use-from-trait.rs                |  2 +-
 tests/ui/use/use-from-trait.stderr            | 12 +++--
 20 files changed, 168 insertions(+), 113 deletions(-)
 delete mode 100644 tests/ui/error-codes/E0253.rs
 delete mode 100644 tests/ui/error-codes/E0253.stderr
 create mode 100644 tests/ui/use/import_trait_associated_item_bad.rs
 create mode 100644 tests/ui/use/import_trait_associated_item_bad.stderr
 create mode 100644 tests/ui/use/import_trait_associated_item_glob.rs

diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md
index 705d1bfc53e59..628f5e252fbb6 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0253.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0253.md
@@ -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;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index fcb7382549f43..5e79e93201531 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -1770,7 +1770,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
     ) -> Ty<'tcx> {
         match self.lower_qpath_shared(
@@ -1795,7 +1795,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
     ) -> Const<'tcx> {
         match self.lower_qpath_shared(
@@ -1820,7 +1820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
         assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
@@ -1840,7 +1840,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?self_ty);
 
         let trait_ref =
-            self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
+            self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
         debug!(?trait_ref);
 
         let item_args =
@@ -2196,16 +2196,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
             }
             Res::Def(DefKind::AssocTy, def_id) => {
-                debug_assert!(path.segments.len() >= 2);
-                let _ = self.prohibit_generic_args(
-                    path.segments[..path.segments.len() - 2].iter(),
-                    GenericsArgsErrExtend::None,
-                );
+                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
+                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
+                    Some(trait_)
+                } else {
+                    None
+                };
                 self.lower_qpath_ty(
                     span,
                     opt_self_ty,
                     def_id,
-                    &path.segments[path.segments.len() - 2],
+                    trait_segment,
                     path.segments.last().unwrap(),
                 )
             }
@@ -2413,16 +2414,17 @@ 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);
-                let _ = self.prohibit_generic_args(
-                    path.segments[..path.segments.len() - 2].iter(),
-                    GenericsArgsErrExtend::None,
-                );
+                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
+                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
+                    Some(trait_)
+                } else {
+                    None
+                };
                 self.lower_qpath_const(
                     span,
                     opt_self_ty,
                     did,
-                    &path.segments[path.segments.len() - 2],
+                    trait_segment,
                     path.segments.last().unwrap(),
                 )
             }
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 558a01713dc7c..38cdfa72a14dd 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -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}
@@ -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
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 363a75911ad43..74daad0839469 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -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;
                 }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index e26b300f13ef7..7fe74378b6748 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -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,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 762e08b2be5f0..816efd0d5fa2d 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -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,
@@ -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(
@@ -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.swap_remove(&import);
+                            });
                         }
-                        let key = BindingKey::new(target, ns);
-                        this.update_resolution(parent, key, false, |_, resolution| {
-                            resolution.single_imports.swap_remove(&import);
-                        });
                     }
+                    Err(Undetermined) => indeterminate_count += 1,
                 }
             }
         });
@@ -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);
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index d2da3ac7d86fe..d23e588e2e3de 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -949,14 +949,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> {
diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs
deleted file mode 100644
index 8284f791c6480..0000000000000
--- a/tests/ui/error-codes/E0253.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-mod foo {
-    pub trait MyTrait {
-        type SomeType;
-    }
-}
-
-use foo::MyTrait::SomeType;
-    //~^ ERROR E0253
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr
deleted file mode 100644
index 954dbc8169395..0000000000000
--- a/tests/ui/error-codes/E0253.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0253]: `SomeType` is not directly importable
-  --> $DIR/E0253.rs:7:5
-   |
-LL | use foo::MyTrait::SomeType;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0253`.
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
index aec13fb020288..c2c010eaba636 100644
--- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
@@ -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() {}
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
index d342f5bd5512e..fca3cef3e203d 100644
--- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
@@ -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`.
diff --git a/tests/ui/imports/issue-30560.rs b/tests/ui/imports/issue-30560.rs
index d8d4ca608f1c0..fe5d17c187364 100644
--- a/tests/ui/imports/issue-30560.rs
+++ b/tests/ui/imports/issue-30560.rs
@@ -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() {}
diff --git a/tests/ui/imports/issue-30560.stderr b/tests/ui/imports/issue-30560.stderr
index 69cfd4c06a8b8..89492261cbaff 100644
--- a/tests/ui/imports/issue-30560.stderr
+++ b/tests/ui/imports/issue-30560.stderr
@@ -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
    |
@@ -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`.
diff --git a/tests/ui/use/import_trait_associated_item_bad.rs b/tests/ui/use/import_trait_associated_item_bad.rs
new file mode 100644
index 0000000000000..d3d2a8e83cdde
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_bad.rs
@@ -0,0 +1,18 @@
+#![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 ambiguous associated type
+type Alias2 = self::AssocTy; //~ ERROR ambiguous associated type
+
+use Trait::CONST;
+type Alias3 = [u8; CONST]; //~ ERROR ambiguous associated constant
+type Alias4 = [u8; self::CONST]; //~ ERROR ambiguous associated constant
+
+fn main() {}
diff --git a/tests/ui/use/import_trait_associated_item_bad.stderr b/tests/ui/use/import_trait_associated_item_bad.stderr
new file mode 100644
index 0000000000000..d5cd5d37bd714
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_bad.stderr
@@ -0,0 +1,49 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/import_trait_associated_item_bad.rs:11:15
+   |
+LL | type Alias1 = AssocTy;
+   |               ^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL | type Alias1 = <Example as Trait>::AssocTy;
+   |               ++++++++++++++++++++
+
+error[E0223]: ambiguous associated type
+  --> $DIR/import_trait_associated_item_bad.rs:12:15
+   |
+LL | type Alias2 = self::AssocTy;
+   |               ^^^^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL - type Alias2 = self::AssocTy;
+LL + type Alias2 = <Example as Trait>::AssocTy;
+   |
+
+error[E0223]: ambiguous associated constant
+  --> $DIR/import_trait_associated_item_bad.rs:15:20
+   |
+LL | type Alias3 = [u8; CONST];
+   |                    ^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL | type Alias3 = [u8; <Example as Trait>::CONST];
+   |                    ++++++++++++++++++++
+
+error[E0223]: ambiguous associated constant
+  --> $DIR/import_trait_associated_item_bad.rs:16:20
+   |
+LL | type Alias4 = [u8; self::CONST];
+   |                    ^^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL - type Alias4 = [u8; self::CONST];
+LL + type Alias4 = [u8; <Example as Trait>::CONST];
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/use/import_trait_associated_item_glob.rs b/tests/ui/use/import_trait_associated_item_glob.rs
new file mode 100644
index 0000000000000..8a712514ed598
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_glob.rs
@@ -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();
+}
diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs
index b030892aa2695..220bf8cad46f3 100644
--- a/tests/ui/use/use-from-trait-xc.rs
+++ b/tests/ui/use/use-from-trait-xc.rs
@@ -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]
diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr
index 0f8440aa53079..c8ee29b18d0c4 100644
--- a/tests/ui/use/use-from-trait-xc.stderr
+++ b/tests/ui/use/use-from-trait-xc.stderr
@@ -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
@@ -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`.
diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs
index 89b7aaa4ba38e..cab661a29e8eb 100644
--- a/tests/ui/use/use-from-trait.rs
+++ b/tests/ui/use/use-from-trait.rs
@@ -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]
diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr
index 2dd78a3545298..63cfcc207504b 100644
--- a/tests/ui/use/use-from-trait.stderr
+++ b/tests/ui/use/use-from-trait.stderr
@@ -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
@@ -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`.