about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs45
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs16
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0253.md6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs34
-rw-r--r--compiler/rustc_resolve/messages.ftl7
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs8
-rw-r--r--compiler/rustc_resolve/src/errors.rs16
-rw-r--r--compiler/rustc_resolve/src/imports.rs43
-rw-r--r--compiler/rustc_resolve/src/lib.rs10
10 files changed, 90 insertions, 103 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
index b2ed8a35827..8e04791461b 100644
--- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
@@ -7,6 +7,8 @@ use rustc_middle::ty::RegionVid;
 
 use crate::RegionInferenceContext;
 use crate::constraints::ConstraintSccIndex;
+use crate::region_infer::ConstraintSccs;
+use crate::universal_regions::UniversalRegions;
 
 pub(crate) struct ReverseSccGraph {
     graph: VecGraph<ConstraintSccIndex>,
@@ -19,6 +21,29 @@ pub(crate) struct ReverseSccGraph {
 }
 
 impl ReverseSccGraph {
+    pub(super) fn compute(
+        constraint_sccs: &ConstraintSccs,
+        universal_regions: &UniversalRegions<'_>,
+    ) -> Self {
+        let graph = constraint_sccs.reverse();
+        let mut paired_scc_regions = universal_regions
+            .universal_regions_iter()
+            .map(|region| (constraint_sccs.scc(region), region))
+            .collect::<Vec<_>>();
+        paired_scc_regions.sort();
+        let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect();
+
+        let mut scc_regions = FxIndexMap::default();
+        let mut start = 0;
+        for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) {
+            let (scc, _) = chunk[0];
+
+            scc_regions.insert(scc, start..start + chunk.len());
+            start += chunk.len();
+        }
+        ReverseSccGraph { graph, scc_regions, universal_regions }
+    }
+
     /// Find all universal regions that are required to outlive the given SCC.
     pub(super) fn upper_bounds(&self, scc0: ConstraintSccIndex) -> impl Iterator<Item = RegionVid> {
         let mut duplicates = FxIndexSet::default();
@@ -40,23 +65,7 @@ impl RegionInferenceContext<'_> {
             return;
         }
 
-        let graph = self.constraint_sccs.reverse();
-        let mut paired_scc_regions = self
-            .universal_regions()
-            .universal_regions_iter()
-            .map(|region| (self.constraint_sccs.scc(region), region))
-            .collect::<Vec<_>>();
-        paired_scc_regions.sort();
-        let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect();
-
-        let mut scc_regions = FxIndexMap::default();
-        let mut start = 0;
-        for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) {
-            let (scc, _) = chunk[0];
-            scc_regions.insert(scc, start..start + chunk.len());
-            start += chunk.len();
-        }
-
-        self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions });
+        self.rev_scc_graph =
+            Some(ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions()));
     }
 }
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 536a27763d2..92732aba29b 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -41,8 +41,8 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
 
 pub(crate) struct CreateResult<'tcx> {
     pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
-    pub(crate) known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+    pub(crate) region_bound_pairs: Frozen<RegionBoundPairs<'tcx>>,
+    pub(crate) known_type_outlives_obligations: Frozen<Vec<ty::PolyTypeOutlivesPredicate<'tcx>>>,
     pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
 }
 
@@ -333,8 +333,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 outlives: self.outlives.freeze(),
                 inverse_outlives: self.inverse_outlives.freeze(),
             }),
-            known_type_outlives_obligations,
-            region_bound_pairs: self.region_bound_pairs,
+            known_type_outlives_obligations: Frozen::freeze(known_type_outlives_obligations),
+            region_bound_pairs: Frozen::freeze(self.region_bound_pairs),
             normalized_inputs_and_output,
         }
     }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 99a544279b9..8c512257120 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -151,8 +151,8 @@ pub(crate) fn type_check<'a, 'tcx>(
         body,
         promoted,
         user_type_annotations: &body.user_type_annotations,
-        region_bound_pairs,
-        known_type_outlives_obligations,
+        region_bound_pairs: &region_bound_pairs,
+        known_type_outlives_obligations: &known_type_outlives_obligations,
         reported_errors: Default::default(),
         universal_regions: &universal_region_relations.universal_regions,
         location_table,
@@ -216,8 +216,8 @@ struct TypeChecker<'a, 'tcx> {
     /// User type annotations are shared between the main MIR and the MIR of
     /// all of the promoted items.
     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
-    region_bound_pairs: RegionBoundPairs<'tcx>,
-    known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
+    known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
     reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
     universal_regions: &'a UniversalRegions<'tcx>,
     location_table: &'a PoloniusLocationTable,
@@ -412,9 +412,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         constraint_conversion::ConstraintConversion::new(
             self.infcx,
             self.universal_regions,
-            &self.region_bound_pairs,
+            self.region_bound_pairs,
             self.infcx.param_env,
-            &self.known_type_outlives_obligations,
+            self.known_type_outlives_obligations,
             locations,
             locations.span(self.body),
             category,
@@ -2506,9 +2506,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             constraint_conversion::ConstraintConversion::new(
                 self.infcx,
                 self.universal_regions,
-                &self.region_bound_pairs,
+                self.region_bound_pairs,
                 self.infcx.param_env,
-                &self.known_type_outlives_obligations,
+                self.known_type_outlives_obligations,
                 locations,
                 self.body.span,             // irrelevant; will be overridden.
                 ConstraintCategory::Boring, // same as above.
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> {