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 09cf870bcf35a..4976456afcb31 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 b51b740d08e2e..7d38a6e5f33c1 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 ::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 = impl Sized; @@ -105,9 +97,9 @@ pub(crate) fn insert_outlives_predicate<'tcx>( // struct Ss<'a, T>(&'a Opaque); // ``` // - // Here we want to have an implied bound `Opaque: 'a` - - let ty = tcx.mk_opaque(def_id, substs); + // Here we want to add an explicit `where ::Item: 'a` + // or `Opaque: '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 533a3c768eb16..7fbe49ce92233 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2256,9 +2256,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 aa2b5d067d266..31451192bc50e 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>), - - 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 33543135ddb0e..52c3d97f24111 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 a85e6a19b11b6..4a93597a643f8 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 40bbec8ddd091..66bbf47c3b6e6 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 9a427ceacd0a7..fda5ffe784678 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 8f0bd3a9abe5e..6fedb0ed8ac53 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -249,17 +249,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<::Assoc>: 'a`. - // With this, we can deduce that `::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 543f5b87e00bc..2a68315fefc56 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 30073b541ecbd..8f64eb3e4baf6 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::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 010233d7718c2..d457a4a2beaf5 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