diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2025-03-19 16:11:45 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2025-05-02 15:59:38 +0300 |
| commit | 3eee3dad5c8aa36a88d6ed2e927c53f2ba174819 (patch) | |
| tree | 8227bede38db3d69f70680cd6424d3808bc259f8 /compiler | |
| parent | db074a06fe6649f9455dff8ad3eddd60683036f3 (diff) | |
| download | rust-3eee3dad5c8aa36a88d6ed2e927c53f2ba174819.tar.gz rust-3eee3dad5c8aa36a88d6ed2e927c53f2ba174819.zip | |
resolve: Support imports of associated types and glob imports from traits
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0253.md | 6 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 7 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/imports.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 10 |
7 files changed, 51 insertions, 73 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index 705d1bfc53e..628f5e252fb 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 fcb7382549f..5e79e932015 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 558a01713dc..38cdfa72a14 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 363a75911ad..74daad08394 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 e26b300f13e..7fe74378b67 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 762e08b2be5..816efd0d5fa 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 d2da3ac7d86..d23e588e2e3 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> { |
