Skip to content

Commit 6b49435

Browse files
authored
Rollup merge of #106829 - compiler-errors:more-alias-combine, r=spastorino
Unify `Opaque`/`Projection` handling in region outlives code They share basically identical paths in most places which are even easier to unify now that they're both `ty::Alias` r? types
2 parents 9cda9e0 + 1ea6862 commit 6b49435

File tree

12 files changed

+54
-114
lines changed

12 files changed

+54
-114
lines changed

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
359359
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
360360
}
361361

362-
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
362+
OutlivesBound::RegionSubAlias(r_a, kind, alias_b) => {
363363
self.region_bound_pairs
364-
.insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
365-
}
366-
367-
OutlivesBound::RegionSubOpaque(r_a, def_id, substs) => {
368-
self.region_bound_pairs
369-
.insert(ty::OutlivesPredicate(GenericKind::Opaque(def_id, substs), r_a));
364+
.insert(ty::OutlivesPredicate(GenericKind::Alias(kind, alias_b), r_a));
370365
}
371366
}
372367
}

compiler/rustc_hir_analysis/src/outlives/utils.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -80,34 +80,26 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
8080
.or_insert(span);
8181
}
8282

83-
Component::Projection(proj_ty) => {
84-
// This would arise from something like:
83+
Component::Alias(kind, alias) => {
84+
// This would either arise from something like:
8585
//
8686
// ```
8787
// struct Foo<'a, T: Iterator> {
8888
// x: &'a <T as Iterator>::Item
8989
// }
9090
// ```
9191
//
92-
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`.
93-
let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.def_id, proj_ty.substs);
94-
required_predicates
95-
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
96-
.or_insert(span);
97-
}
98-
99-
Component::Opaque(def_id, substs) => {
100-
// This would arise from something like:
92+
// or:
10193
//
10294
// ```rust
10395
// type Opaque<T> = impl Sized;
10496
// fn defining<T>() -> Opaque<T> {}
10597
// struct Ss<'a, T>(&'a Opaque<T>);
10698
// ```
10799
//
108-
// Here we want to have an implied bound `Opaque<T>: 'a`
109-
110-
let ty = tcx.mk_opaque(def_id, substs);
100+
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`
101+
// or `Opaque<T>: 'a` depending on the alias kind.
102+
let ty: Ty<'tcx> = tcx.mk_ty(ty::Alias(kind, alias));
111103
required_predicates
112104
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
113105
.or_insert(span);

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -2272,9 +2272,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22722272

22732273
let labeled_user_string = match bound_kind {
22742274
GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
2275-
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
2276-
GenericKind::Opaque(def_id, substs) => {
2277-
format!("the opaque type `{}`", self.tcx.def_path_str_with_substs(def_id, substs))
2275+
GenericKind::Alias(ty::Projection, ref p) => format!("the associated type `{}`", p),
2276+
GenericKind::Alias(ty::Opaque, ref p) => {
2277+
format!(
2278+
"the opaque type `{}`",
2279+
self.tcx.def_path_str_with_substs(p.def_id, p.substs)
2280+
)
22782281
}
22792282
};
22802283

compiler/rustc_infer/src/infer/outlives/components.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
// RFC for reference.
44

55
use rustc_data_structures::sso::SsoHashSet;
6-
use rustc_hir::def_id::DefId;
76
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
8-
use rustc_middle::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitable};
7+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
98
use smallvec::{smallvec, SmallVec};
109

1110
#[derive(Debug)]
@@ -23,7 +22,7 @@ pub enum Component<'tcx> {
2322
// is not in a position to judge which is the best technique, so
2423
// we just product the projection as a component and leave it to
2524
// the consumer to decide (but see `EscapingProjection` below).
26-
Projection(ty::AliasTy<'tcx>),
25+
Alias(ty::AliasKind, ty::AliasTy<'tcx>),
2726

2827
// In the case where a projection has escaping regions -- meaning
2928
// regions bound within the type itself -- we always use
@@ -46,8 +45,6 @@ pub enum Component<'tcx> {
4645
// them. This gives us room to improve the regionck reasoning in
4746
// the future without breaking backwards compat.
4847
EscapingProjection(Vec<Component<'tcx>>),
49-
50-
Opaque(DefId, SubstsRef<'tcx>),
5148
}
5249

5350
/// Push onto `out` all the things that must outlive `'a` for the condition
@@ -130,8 +127,8 @@ fn compute_components<'tcx>(
130127
// outlives any other lifetime, which is unsound.
131128
// See https://github.com/rust-lang/rust/issues/84305 for
132129
// more details.
133-
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
134-
out.push(Component::Opaque(def_id, substs));
130+
ty::Alias(ty::Opaque, data) => {
131+
out.push(Component::Alias(ty::Opaque, data));
135132
},
136133

137134
// For projections, we prefer to generate an obligation like
@@ -142,15 +139,15 @@ fn compute_components<'tcx>(
142139
// trait-ref. Therefore, if we see any higher-ranked regions,
143140
// we simply fallback to the most restrictive rule, which
144141
// requires that `Pi: 'a` for all `i`.
145-
ty::Alias(ty::Projection, ref data) => {
142+
ty::Alias(ty::Projection, data) => {
146143
if !data.has_escaping_bound_vars() {
147144
// best case: no escaping regions, so push the
148145
// projection and skip the subtree (thus generating no
149146
// constraints for Pi). This defers the choice between
150147
// the rules OutlivesProjectionEnv,
151148
// OutlivesProjectionTraitDef, and
152149
// OutlivesProjectionComponents to regionck.
153-
out.push(Component::Projection(*data));
150+
out.push(Component::Alias(ty::Projection, data));
154151
} else {
155152
// fallback case: hard code
156153
// OutlivesProjectionComponents. Continue walking

compiler/rustc_infer/src/infer/outlives/env.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,9 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
138138
self.region_bound_pairs
139139
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
140140
}
141-
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
141+
OutlivesBound::RegionSubAlias(r_a, kind, projection_b) => {
142142
self.region_bound_pairs
143-
.insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
144-
}
145-
OutlivesBound::RegionSubOpaque(r_a, def_id, substs) => {
146-
self.region_bound_pairs
147-
.insert(ty::OutlivesPredicate(GenericKind::Opaque(def_id, substs), r_a));
143+
.insert(ty::OutlivesPredicate(GenericKind::Alias(kind, projection_b), r_a));
148144
}
149145
OutlivesBound::RegionSubRegion(r_a, r_b) => {
150146
if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {

compiler/rustc_infer/src/infer/outlives/obligations.rs

+13-35
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,8 @@ where
266266
Component::Param(param_ty) => {
267267
self.param_ty_must_outlive(origin, region, *param_ty);
268268
}
269-
Component::Opaque(def_id, substs) => {
270-
self.opaque_must_outlive(*def_id, substs, origin, region)
271-
}
272-
Component::Projection(projection_ty) => {
273-
self.projection_must_outlive(origin, region, *projection_ty);
269+
Component::Alias(kind, data) => {
270+
self.alias_must_outlive(*kind, *data, origin, region)
274271
}
275272
Component::EscapingProjection(subcomponents) => {
276273
self.components_must_outlive(origin, &subcomponents, region, category);
@@ -305,44 +302,25 @@ where
305302
}
306303

307304
#[instrument(level = "debug", skip(self))]
308-
fn opaque_must_outlive(
305+
fn alias_must_outlive(
309306
&mut self,
310-
def_id: DefId,
311-
substs: SubstsRef<'tcx>,
307+
kind: ty::AliasKind,
308+
data: ty::AliasTy<'tcx>,
312309
origin: infer::SubregionOrigin<'tcx>,
313310
region: ty::Region<'tcx>,
314311
) {
315312
self.generic_must_outlive(
316313
origin,
317314
region,
318-
GenericKind::Opaque(def_id, substs),
319-
def_id,
320-
substs,
321-
true,
315+
GenericKind::Alias(kind, data),
316+
data.def_id,
317+
data.substs,
318+
kind == ty::Opaque,
322319
|ty| match *ty.kind() {
323-
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => (def_id, substs),
324-
_ => bug!("expected only projection types from env, not {:?}", ty),
325-
},
326-
);
327-
}
328-
329-
#[instrument(level = "debug", skip(self))]
330-
fn projection_must_outlive(
331-
&mut self,
332-
origin: infer::SubregionOrigin<'tcx>,
333-
region: ty::Region<'tcx>,
334-
projection_ty: ty::AliasTy<'tcx>,
335-
) {
336-
self.generic_must_outlive(
337-
origin,
338-
region,
339-
GenericKind::Projection(projection_ty),
340-
projection_ty.def_id,
341-
projection_ty.substs,
342-
false,
343-
|ty| match ty.kind() {
344-
ty::Alias(ty::Projection, projection_ty) => {
345-
(projection_ty.def_id, projection_ty.substs)
320+
ty::Alias(filter_kind, ty::AliasTy { def_id, substs, .. })
321+
if kind == filter_kind =>
322+
{
323+
(def_id, substs)
346324
}
347325
_ => bug!("expected only projection types from env, not {:?}", ty),
348326
},

compiler/rustc_infer/src/infer/outlives/verify.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
170170
match *component {
171171
Component::Region(lt) => VerifyBound::OutlivedBy(lt),
172172
Component::Param(param_ty) => self.param_bound(param_ty),
173-
Component::Opaque(did, substs) => self.projection_opaque_bounds(
174-
GenericKind::Opaque(did, substs),
175-
did,
176-
substs,
177-
visited,
178-
),
179-
Component::Projection(projection_ty) => self.projection_opaque_bounds(
180-
GenericKind::Projection(projection_ty),
181-
projection_ty.def_id,
182-
projection_ty.substs,
173+
Component::Alias(kind, data) => self.projection_opaque_bounds(
174+
GenericKind::Alias(kind, data),
175+
data.def_id,
176+
data.substs,
183177
visited,
184178
),
185179
Component::EscapingProjection(ref components) => {

compiler/rustc_infer/src/infer/region_constraints/mod.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ use rustc_data_structures::intern::Interned;
1212
use rustc_data_structures::sync::Lrc;
1313
use rustc_data_structures::undo_log::UndoLogs;
1414
use rustc_data_structures::unify as ut;
15-
use rustc_hir::def_id::DefId;
1615
use rustc_index::vec::IndexVec;
1716
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
18-
use rustc_middle::ty::subst::SubstsRef;
1917
use rustc_middle::ty::ReStatic;
2018
use rustc_middle::ty::{self, Ty, TyCtxt};
2119
use rustc_middle::ty::{ReLateBound, ReVar};
@@ -169,8 +167,7 @@ pub struct Verify<'tcx> {
169167
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
170168
pub enum GenericKind<'tcx> {
171169
Param(ty::ParamTy),
172-
Projection(ty::AliasTy<'tcx>),
173-
Opaque(DefId, SubstsRef<'tcx>),
170+
Alias(ty::AliasKind, ty::AliasTy<'tcx>),
174171
}
175172

176173
/// Describes the things that some `GenericKind` value `G` is known to
@@ -749,9 +746,9 @@ impl<'tcx> fmt::Debug for GenericKind<'tcx> {
749746
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
750747
match *self {
751748
GenericKind::Param(ref p) => write!(f, "{:?}", p),
752-
GenericKind::Projection(ref p) => write!(f, "{:?}", p),
753-
GenericKind::Opaque(def_id, substs) => ty::tls::with(|tcx| {
754-
write!(f, "{}", tcx.def_path_str_with_substs(def_id, tcx.lift(substs).unwrap()))
749+
GenericKind::Alias(ty::Projection, ref p) => write!(f, "{:?}", p),
750+
GenericKind::Alias(ty::Opaque, ref p) => ty::tls::with(|tcx| {
751+
write!(f, "{}", tcx.def_path_str_with_substs(p.def_id, tcx.lift(p.substs).unwrap()))
755752
}),
756753
}
757754
}
@@ -761,9 +758,9 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
761758
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
762759
match *self {
763760
GenericKind::Param(ref p) => write!(f, "{}", p),
764-
GenericKind::Projection(ref p) => write!(f, "{}", p),
765-
GenericKind::Opaque(def_id, substs) => ty::tls::with(|tcx| {
766-
write!(f, "{}", tcx.def_path_str_with_substs(def_id, tcx.lift(substs).unwrap()))
761+
GenericKind::Alias(ty::Projection, ref p) => write!(f, "{}", p),
762+
GenericKind::Alias(ty::Opaque, ref p) => ty::tls::with(|tcx| {
763+
write!(f, "{}", tcx.def_path_str_with_substs(p.def_id, tcx.lift(p.substs).unwrap()))
767764
}),
768765
}
769766
}
@@ -773,8 +770,7 @@ impl<'tcx> GenericKind<'tcx> {
773770
pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
774771
match *self {
775772
GenericKind::Param(ref p) => p.to_ty(tcx),
776-
GenericKind::Projection(ref p) => tcx.mk_projection(p.def_id, p.substs),
777-
GenericKind::Opaque(def_id, substs) => tcx.mk_opaque(def_id, substs),
773+
GenericKind::Alias(kind, data) => tcx.mk_ty(ty::Alias(kind, data)),
778774
}
779775
}
780776
}

compiler/rustc_infer/src/traits/util.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -261,17 +261,8 @@ impl<'tcx> Elaborator<'tcx> {
261261

262262
Component::UnresolvedInferenceVariable(_) => None,
263263

264-
Component::Opaque(def_id, substs) => {
265-
let ty = tcx.mk_opaque(def_id, substs);
266-
Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
267-
ty::OutlivesPredicate(ty, r_min),
268-
)))
269-
}
270-
271-
Component::Projection(projection) => {
272-
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
273-
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
274-
let ty = tcx.mk_projection(projection.def_id, projection.substs);
264+
Component::Alias(kind, data) => {
265+
let ty = tcx.mk_ty(ty::Alias(kind, data));
275266
Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
276267
ty::OutlivesPredicate(ty, r_min),
277268
)))

compiler/rustc_middle/src/traits/query.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
use crate::error::DropCheckOverflow;
99
use crate::infer::canonical::{Canonical, QueryResponse};
1010
use crate::ty::error::TypeError;
11-
use crate::ty::subst::{GenericArg, SubstsRef};
11+
use crate::ty::subst::GenericArg;
1212
use crate::ty::{self, Ty, TyCtxt};
13-
use rustc_hir::def_id::DefId;
1413
use rustc_span::source_map::Span;
1514

1615
pub mod type_op {
@@ -214,6 +213,5 @@ pub struct NormalizationResult<'tcx> {
214213
pub enum OutlivesBound<'tcx> {
215214
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
216215
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
217-
RegionSubProjection(ty::Region<'tcx>, ty::AliasTy<'tcx>),
218-
RegionSubOpaque(ty::Region<'tcx>, DefId, SubstsRef<'tcx>),
216+
RegionSubAlias(ty::Region<'tcx>, ty::AliasKind, ty::AliasTy<'tcx>),
219217
}

compiler/rustc_middle/src/ty/structural_impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ TrivialTypeTraversalAndLiftImpls! {
227227
crate::ty::BoundRegionKind,
228228
crate::ty::AssocItem,
229229
crate::ty::AssocKind,
230+
crate::ty::AliasKind,
230231
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
231232
crate::ty::ClosureKind,
232233
crate::ty::FreeRegion,

compiler/rustc_traits/src/implied_outlives_bounds.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,8 @@ fn implied_bounds_from_components<'tcx>(
154154
match component {
155155
Component::Region(r) => Some(OutlivesBound::RegionSubRegion(sub_region, r)),
156156
Component::Param(p) => Some(OutlivesBound::RegionSubParam(sub_region, p)),
157-
Component::Projection(p) => Some(OutlivesBound::RegionSubProjection(sub_region, p)),
158-
Component::Opaque(def_id, substs) => {
159-
Some(OutlivesBound::RegionSubOpaque(sub_region, def_id, substs))
157+
Component::Alias(kind, p) => {
158+
Some(OutlivesBound::RegionSubAlias(sub_region, kind, p))
160159
}
161160
Component::EscapingProjection(_) =>
162161
// If the projection has escaping regions, don't

0 commit comments

Comments
 (0)