about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs20
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs15
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs8
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs48
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs14
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs20
-rw-r--r--compiler/rustc_infer/src/traits/util.rs13
-rw-r--r--compiler/rustc_middle/src/traits/query.rs6
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs5
12 files changed, 54 insertions, 114 deletions
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 09cf870bcf3..4976456afcb 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -359,14 +359,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                         .insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
                 }
 
-                OutlivesBound::RegionSubProjection(r_a, projection_b) => {
+                OutlivesBound::RegionSubAlias(r_a, kind, alias_b) => {
                     self.region_bound_pairs
-                        .insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
-                }
-
-                OutlivesBound::RegionSubOpaque(r_a, def_id, substs) => {
-                    self.region_bound_pairs
-                        .insert(ty::OutlivesPredicate(GenericKind::Opaque(def_id, substs), r_a));
+                        .insert(ty::OutlivesPredicate(GenericKind::Alias(kind, alias_b), r_a));
                 }
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index b51b740d08e..7d38a6e5f33 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -80,8 +80,8 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
                             .or_insert(span);
                     }
 
-                    Component::Projection(proj_ty) => {
-                        // This would arise from something like:
+                    Component::Alias(kind, alias) => {
+                        // This would either arise from something like:
                         //
                         // ```
                         // struct Foo<'a, T: Iterator> {
@@ -89,15 +89,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
                         // }
                         // ```
                         //
-                        // Here we want to add an explicit `where <T as Iterator>::Item: 'a`.
-                        let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.def_id, proj_ty.substs);
-                        required_predicates
-                            .entry(ty::OutlivesPredicate(ty.into(), outlived_region))
-                            .or_insert(span);
-                    }
-
-                    Component::Opaque(def_id, substs) => {
-                        // This would arise from something like:
+                        // or:
                         //
                         // ```rust
                         // type Opaque<T> = impl Sized;
@@ -105,9 +97,9 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
                         // struct Ss<'a, T>(&'a Opaque<T>);
                         // ```
                         //
-                        // Here we want to have an implied bound `Opaque<T>: 'a`
-
-                        let ty = tcx.mk_opaque(def_id, substs);
+                        // Here we want to add an explicit `where <T as Iterator>::Item: 'a`
+                        // or `Opaque<T>: 'a` depending on the alias kind.
+                        let ty: Ty<'tcx> = tcx.mk_ty(ty::Alias(kind, alias));
                         required_predicates
                             .entry(ty::OutlivesPredicate(ty.into(), outlived_region))
                             .or_insert(span);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index abd99fc74da..9c38eb6163f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2272,9 +2272,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
-            GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
-            GenericKind::Opaque(def_id, substs) => {
-                format!("the opaque type `{}`", self.tcx.def_path_str_with_substs(def_id, substs))
+            GenericKind::Alias(ty::Projection, ref p) => format!("the associated type `{}`", p),
+            GenericKind::Alias(ty::Opaque, ref p) => {
+                format!(
+                    "the opaque type `{}`",
+                    self.tcx.def_path_str_with_substs(p.def_id, p.substs)
+                )
             }
         };
 
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index aa2b5d067d2..31451192bc5 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -3,9 +3,8 @@
 // RFC for reference.
 
 use rustc_data_structures::sso::SsoHashSet;
-use rustc_hir::def_id::DefId;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
-use rustc_middle::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
 use smallvec::{smallvec, SmallVec};
 
 #[derive(Debug)]
@@ -23,7 +22,7 @@ pub enum Component<'tcx> {
     // is not in a position to judge which is the best technique, so
     // we just product the projection as a component and leave it to
     // the consumer to decide (but see `EscapingProjection` below).
-    Projection(ty::AliasTy<'tcx>),
+    Alias(ty::AliasKind, ty::AliasTy<'tcx>),
 
     // In the case where a projection has escaping regions -- meaning
     // regions bound within the type itself -- we always use
@@ -46,8 +45,6 @@ pub enum Component<'tcx> {
     // them. This gives us room to improve the regionck reasoning in
     // the future without breaking backwards compat.
     EscapingProjection(Vec<Component<'tcx>>),
-
-    Opaque(DefId, SubstsRef<'tcx>),
 }
 
 /// Push onto `out` all the things that must outlive `'a` for the condition
@@ -130,8 +127,8 @@ fn compute_components<'tcx>(
             // outlives any other lifetime, which is unsound.
             // See https://github.com/rust-lang/rust/issues/84305 for
             // more details.
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
-                out.push(Component::Opaque(def_id, substs));
+            ty::Alias(ty::Opaque, data) => {
+                out.push(Component::Alias(ty::Opaque, data));
             },
 
             // For projections, we prefer to generate an obligation like
@@ -142,7 +139,7 @@ fn compute_components<'tcx>(
             // trait-ref. Therefore, if we see any higher-ranked regions,
             // we simply fallback to the most restrictive rule, which
             // requires that `Pi: 'a` for all `i`.
-            ty::Alias(ty::Projection, ref data) => {
+            ty::Alias(ty::Projection, data) => {
                 if !data.has_escaping_bound_vars() {
                     // best case: no escaping regions, so push the
                     // projection and skip the subtree (thus generating no
@@ -150,7 +147,7 @@ fn compute_components<'tcx>(
                     // the rules OutlivesProjectionEnv,
                     // OutlivesProjectionTraitDef, and
                     // OutlivesProjectionComponents to regionck.
-                    out.push(Component::Projection(*data));
+                    out.push(Component::Alias(ty::Projection, data));
                 } else {
                     // fallback case: hard code
                     // OutlivesProjectionComponents.  Continue walking
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index 33543135ddb..52c3d97f241 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -138,13 +138,9 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
                     self.region_bound_pairs
                         .insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
                 }
-                OutlivesBound::RegionSubProjection(r_a, projection_b) => {
+                OutlivesBound::RegionSubAlias(r_a, kind, projection_b) => {
                     self.region_bound_pairs
-                        .insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
-                }
-                OutlivesBound::RegionSubOpaque(r_a, def_id, substs) => {
-                    self.region_bound_pairs
-                        .insert(ty::OutlivesPredicate(GenericKind::Opaque(def_id, substs), r_a));
+                        .insert(ty::OutlivesPredicate(GenericKind::Alias(kind, projection_b), r_a));
                 }
                 OutlivesBound::RegionSubRegion(r_a, r_b) => {
                     if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index a85e6a19b11..4a93597a643 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -266,11 +266,8 @@ where
                 Component::Param(param_ty) => {
                     self.param_ty_must_outlive(origin, region, *param_ty);
                 }
-                Component::Opaque(def_id, substs) => {
-                    self.opaque_must_outlive(*def_id, substs, origin, region)
-                }
-                Component::Projection(projection_ty) => {
-                    self.projection_must_outlive(origin, region, *projection_ty);
+                Component::Alias(kind, data) => {
+                    self.alias_must_outlive(*kind, *data, origin, region)
                 }
                 Component::EscapingProjection(subcomponents) => {
                     self.components_must_outlive(origin, &subcomponents, region, category);
@@ -305,44 +302,25 @@ where
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn opaque_must_outlive(
+    fn alias_must_outlive(
         &mut self,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        kind: ty::AliasKind,
+        data: ty::AliasTy<'tcx>,
         origin: infer::SubregionOrigin<'tcx>,
         region: ty::Region<'tcx>,
     ) {
         self.generic_must_outlive(
             origin,
             region,
-            GenericKind::Opaque(def_id, substs),
-            def_id,
-            substs,
-            true,
+            GenericKind::Alias(kind, data),
+            data.def_id,
+            data.substs,
+            kind == ty::Opaque,
             |ty| match *ty.kind() {
-                ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => (def_id, substs),
-                _ => bug!("expected only projection types from env, not {:?}", ty),
-            },
-        );
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn projection_must_outlive(
-        &mut self,
-        origin: infer::SubregionOrigin<'tcx>,
-        region: ty::Region<'tcx>,
-        projection_ty: ty::AliasTy<'tcx>,
-    ) {
-        self.generic_must_outlive(
-            origin,
-            region,
-            GenericKind::Projection(projection_ty),
-            projection_ty.def_id,
-            projection_ty.substs,
-            false,
-            |ty| match ty.kind() {
-                ty::Alias(ty::Projection, projection_ty) => {
-                    (projection_ty.def_id, projection_ty.substs)
+                ty::Alias(filter_kind, ty::AliasTy { def_id, substs, .. })
+                    if kind == filter_kind =>
+                {
+                    (def_id, substs)
                 }
                 _ => bug!("expected only projection types from env, not {:?}", ty),
             },
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 40bbec8ddd0..66bbf47c3b6 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -170,16 +170,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         match *component {
             Component::Region(lt) => VerifyBound::OutlivedBy(lt),
             Component::Param(param_ty) => self.param_bound(param_ty),
-            Component::Opaque(did, substs) => self.projection_opaque_bounds(
-                GenericKind::Opaque(did, substs),
-                did,
-                substs,
-                visited,
-            ),
-            Component::Projection(projection_ty) => self.projection_opaque_bounds(
-                GenericKind::Projection(projection_ty),
-                projection_ty.def_id,
-                projection_ty.substs,
+            Component::Alias(kind, data) => self.projection_opaque_bounds(
+                GenericKind::Alias(kind, data),
+                data.def_id,
+                data.substs,
                 visited,
             ),
             Component::EscapingProjection(ref components) => {
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 9a427ceacd0..fda5ffe7846 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -12,10 +12,8 @@ use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_data_structures::unify as ut;
-use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
-use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::ReStatic;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ReLateBound, ReVar};
@@ -169,8 +167,7 @@ pub struct Verify<'tcx> {
 #[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
 pub enum GenericKind<'tcx> {
     Param(ty::ParamTy),
-    Projection(ty::AliasTy<'tcx>),
-    Opaque(DefId, SubstsRef<'tcx>),
+    Alias(ty::AliasKind, ty::AliasTy<'tcx>),
 }
 
 /// Describes the things that some `GenericKind` value `G` is known to
@@ -749,9 +746,9 @@ impl<'tcx> fmt::Debug for GenericKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             GenericKind::Param(ref p) => write!(f, "{:?}", p),
-            GenericKind::Projection(ref p) => write!(f, "{:?}", p),
-            GenericKind::Opaque(def_id, substs) => ty::tls::with(|tcx| {
-                write!(f, "{}", tcx.def_path_str_with_substs(def_id, tcx.lift(substs).unwrap()))
+            GenericKind::Alias(ty::Projection, ref p) => write!(f, "{:?}", p),
+            GenericKind::Alias(ty::Opaque, ref p) => ty::tls::with(|tcx| {
+                write!(f, "{}", tcx.def_path_str_with_substs(p.def_id, tcx.lift(p.substs).unwrap()))
             }),
         }
     }
@@ -761,9 +758,9 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             GenericKind::Param(ref p) => write!(f, "{}", p),
-            GenericKind::Projection(ref p) => write!(f, "{}", p),
-            GenericKind::Opaque(def_id, substs) => ty::tls::with(|tcx| {
-                write!(f, "{}", tcx.def_path_str_with_substs(def_id, tcx.lift(substs).unwrap()))
+            GenericKind::Alias(ty::Projection, ref p) => write!(f, "{}", p),
+            GenericKind::Alias(ty::Opaque, ref p) => ty::tls::with(|tcx| {
+                write!(f, "{}", tcx.def_path_str_with_substs(p.def_id, tcx.lift(p.substs).unwrap()))
             }),
         }
     }
@@ -773,8 +770,7 @@ impl<'tcx> GenericKind<'tcx> {
     pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             GenericKind::Param(ref p) => p.to_ty(tcx),
-            GenericKind::Projection(ref p) => tcx.mk_projection(p.def_id, p.substs),
-            GenericKind::Opaque(def_id, substs) => tcx.mk_opaque(def_id, substs),
+            GenericKind::Alias(kind, data) => tcx.mk_ty(ty::Alias(kind, data)),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 1817bbf9228..fb448ec0222 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -261,17 +261,8 @@ impl<'tcx> Elaborator<'tcx> {
 
                             Component::UnresolvedInferenceVariable(_) => None,
 
-                            Component::Opaque(def_id, substs) => {
-                                let ty = tcx.mk_opaque(def_id, substs);
-                                Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
-                                    ty::OutlivesPredicate(ty, r_min),
-                                )))
-                            }
-
-                            Component::Projection(projection) => {
-                                // We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
-                                // With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
-                                let ty = tcx.mk_projection(projection.def_id, projection.substs);
+                            Component::Alias(kind, data) => {
+                                let ty = tcx.mk_ty(ty::Alias(kind, data));
                                 Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
                                     ty::OutlivesPredicate(ty, r_min),
                                 )))
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 543f5b87e00..2a68315fefc 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -8,9 +8,8 @@
 use crate::error::DropCheckOverflow;
 use crate::infer::canonical::{Canonical, QueryResponse};
 use crate::ty::error::TypeError;
-use crate::ty::subst::{GenericArg, SubstsRef};
+use crate::ty::subst::GenericArg;
 use crate::ty::{self, Ty, TyCtxt};
-use rustc_hir::def_id::DefId;
 use rustc_span::source_map::Span;
 
 pub mod type_op {
@@ -214,6 +213,5 @@ pub struct NormalizationResult<'tcx> {
 pub enum OutlivesBound<'tcx> {
     RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
     RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
-    RegionSubProjection(ty::Region<'tcx>, ty::AliasTy<'tcx>),
-    RegionSubOpaque(ty::Region<'tcx>, DefId, SubstsRef<'tcx>),
+    RegionSubAlias(ty::Region<'tcx>, ty::AliasKind, ty::AliasTy<'tcx>),
 }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 30073b541ec..8f64eb3e4ba 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -227,6 +227,7 @@ TrivialTypeTraversalAndLiftImpls! {
     crate::ty::BoundRegionKind,
     crate::ty::AssocItem,
     crate::ty::AssocKind,
+    crate::ty::AliasKind,
     crate::ty::Placeholder<crate::ty::BoundRegionKind>,
     crate::ty::ClosureKind,
     crate::ty::FreeRegion,
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 010233d7718..d457a4a2bea 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -154,9 +154,8 @@ fn implied_bounds_from_components<'tcx>(
             match component {
                 Component::Region(r) => Some(OutlivesBound::RegionSubRegion(sub_region, r)),
                 Component::Param(p) => Some(OutlivesBound::RegionSubParam(sub_region, p)),
-                Component::Projection(p) => Some(OutlivesBound::RegionSubProjection(sub_region, p)),
-                Component::Opaque(def_id, substs) => {
-                    Some(OutlivesBound::RegionSubOpaque(sub_region, def_id, substs))
+                Component::Alias(kind, p) => {
+                    Some(OutlivesBound::RegionSubAlias(sub_region, kind, p))
                 }
                 Component::EscapingProjection(_) =>
                 // If the projection has escaping regions, don't