Skip to content

Commit 19423b5

Browse files
committedJan 19, 2023
Auto merge of #106910 - aliemjay:alias-ty-in-regionck, r=oli-obk
even more unify Projection/Opaque handling in region outlives code edit: This continues ate the same pace as #106829. New changes are described in #106910 (comment). ~This touches `OutlivesBound`, `Component`, `GenericKind` enums.~ r? `@oli-obk` (because of overlap with #95474)
2 parents 79335f1 + e40567b commit 19423b5

File tree

13 files changed

+108
-151
lines changed

13 files changed

+108
-151
lines changed
 

‎compiler/rustc_borrowck/src/type_check/free_region_relations.rs

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

362-
OutlivesBound::RegionSubAlias(r_a, kind, alias_b) => {
362+
OutlivesBound::RegionSubAlias(r_a, alias_b) => {
363363
self.region_bound_pairs
364-
.insert(ty::OutlivesPredicate(GenericKind::Alias(kind, alias_b), r_a));
364+
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
365365
}
366366
}
367367
}

‎compiler/rustc_hir_analysis/src/outlives/utils.rs

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

83-
Component::Alias(kind, alias) => {
83+
Component::Alias(alias_ty) => {
8484
// This would either arise from something like:
8585
//
8686
// ```
@@ -99,13 +99,13 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
9999
//
100100
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`
101101
// or `Opaque<T>: 'a` depending on the alias kind.
102-
let ty: Ty<'tcx> = tcx.mk_ty(ty::Alias(kind, alias));
102+
let ty = alias_ty.to_ty(tcx);
103103
required_predicates
104104
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
105105
.or_insert(span);
106106
}
107107

108-
Component::EscapingProjection(_) => {
108+
Component::EscapingAlias(_) => {
109109
// As above, but the projection involves
110110
// late-bound regions. Therefore, the WF
111111
// requirement is not checked in type definition

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

+4-7
Original file line numberDiff line numberDiff line change
@@ -2272,13 +2272,10 @@ 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::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-
)
2281-
}
2275+
GenericKind::Alias(ref p) => match p.kind(self.tcx) {
2276+
ty::AliasKind::Projection => format!("the associated type `{}`", p),
2277+
ty::AliasKind::Opaque => format!("the opaque type `{}`", p),
2278+
},
22822279
};
22832280

22842281
if let Some(SubregionOrigin::CompareImplItemObligation {

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

+6-17
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub enum Component<'tcx> {
2222
// is not in a position to judge which is the best technique, so
2323
// we just product the projection as a component and leave it to
2424
// the consumer to decide (but see `EscapingProjection` below).
25-
Alias(ty::AliasKind, ty::AliasTy<'tcx>),
25+
Alias(ty::AliasTy<'tcx>),
2626

2727
// In the case where a projection has escaping regions -- meaning
2828
// regions bound within the type itself -- we always use
@@ -44,7 +44,7 @@ pub enum Component<'tcx> {
4444
// projection, so that implied bounds code can avoid relying on
4545
// them. This gives us room to improve the regionck reasoning in
4646
// the future without breaking backwards compat.
47-
EscapingProjection(Vec<Component<'tcx>>),
47+
EscapingAlias(Vec<Component<'tcx>>),
4848
}
4949

5050
/// Push onto `out` all the things that must outlive `'a` for the condition
@@ -120,17 +120,6 @@ fn compute_components<'tcx>(
120120
out.push(Component::Param(p));
121121
}
122122

123-
// Ignore lifetimes found in opaque types. Opaque types can
124-
// have lifetimes in their substs which their hidden type doesn't
125-
// actually use. If we inferred that an opaque type is outlived by
126-
// its parameter lifetimes, then we could prove that any lifetime
127-
// outlives any other lifetime, which is unsound.
128-
// See https://github.com/rust-lang/rust/issues/84305 for
129-
// more details.
130-
ty::Alias(ty::Opaque, data) => {
131-
out.push(Component::Alias(ty::Opaque, data));
132-
},
133-
134123
// For projections, we prefer to generate an obligation like
135124
// `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
136125
// regionck more ways to prove that it holds. However,
@@ -139,23 +128,23 @@ fn compute_components<'tcx>(
139128
// trait-ref. Therefore, if we see any higher-ranked regions,
140129
// we simply fallback to the most restrictive rule, which
141130
// requires that `Pi: 'a` for all `i`.
142-
ty::Alias(ty::Projection, data) => {
143-
if !data.has_escaping_bound_vars() {
131+
ty::Alias(_, alias_ty) => {
132+
if !alias_ty.has_escaping_bound_vars() {
144133
// best case: no escaping regions, so push the
145134
// projection and skip the subtree (thus generating no
146135
// constraints for Pi). This defers the choice between
147136
// the rules OutlivesProjectionEnv,
148137
// OutlivesProjectionTraitDef, and
149138
// OutlivesProjectionComponents to regionck.
150-
out.push(Component::Alias(ty::Projection, data));
139+
out.push(Component::Alias(alias_ty));
151140
} else {
152141
// fallback case: hard code
153142
// OutlivesProjectionComponents. Continue walking
154143
// through and constrain Pi.
155144
let mut subcomponents = smallvec![];
156145
let mut subvisited = SsoHashSet::new();
157146
compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited);
158-
out.push(Component::EscapingProjection(subcomponents.into_iter().collect()));
147+
out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
159148
}
160149
}
161150

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
138138
self.region_bound_pairs
139139
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
140140
}
141-
OutlivesBound::RegionSubAlias(r_a, kind, projection_b) => {
141+
OutlivesBound::RegionSubAlias(r_a, alias_b) => {
142142
self.region_bound_pairs
143-
.insert(ty::OutlivesPredicate(GenericKind::Alias(kind, projection_b), r_a));
143+
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
144144
}
145145
OutlivesBound::RegionSubRegion(r_a, r_b) => {
146146
if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {

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

+19-62
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ use crate::infer::{
6767
};
6868
use crate::traits::{ObligationCause, ObligationCauseCode};
6969
use rustc_data_structures::undo_log::UndoLogs;
70-
use rustc_hir::def_id::DefId;
7170
use rustc_middle::mir::ConstraintCategory;
7271
use rustc_middle::ty::subst::GenericArgKind;
7372
use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitable};
@@ -266,10 +265,8 @@ where
266265
Component::Param(param_ty) => {
267266
self.param_ty_must_outlive(origin, region, *param_ty);
268267
}
269-
Component::Alias(kind, data) => {
270-
self.alias_must_outlive(*kind, *data, origin, region)
271-
}
272-
Component::EscapingProjection(subcomponents) => {
268+
Component::Alias(alias_ty) => self.alias_ty_must_outlive(origin, region, *alias_ty),
269+
Component::EscapingAlias(subcomponents) => {
273270
self.components_must_outlive(origin, &subcomponents, region, category);
274271
}
275272
Component::UnresolvedInferenceVariable(v) => {
@@ -285,61 +282,26 @@ where
285282
}
286283
}
287284

285+
#[instrument(level = "debug", skip(self))]
288286
fn param_ty_must_outlive(
289287
&mut self,
290288
origin: infer::SubregionOrigin<'tcx>,
291289
region: ty::Region<'tcx>,
292290
param_ty: ty::ParamTy,
293291
) {
294-
debug!(
295-
"param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})",
296-
region, param_ty, origin
297-
);
298-
299-
let generic = GenericKind::Param(param_ty);
300292
let verify_bound = self.verify_bound.param_bound(param_ty);
301-
self.delegate.push_verify(origin, generic, region, verify_bound);
293+
self.delegate.push_verify(origin, GenericKind::Param(param_ty), region, verify_bound);
302294
}
303295

304296
#[instrument(level = "debug", skip(self))]
305-
fn alias_must_outlive(
297+
fn alias_ty_must_outlive(
306298
&mut self,
307-
kind: ty::AliasKind,
308-
data: ty::AliasTy<'tcx>,
309299
origin: infer::SubregionOrigin<'tcx>,
310300
region: ty::Region<'tcx>,
311-
) {
312-
self.generic_must_outlive(
313-
origin,
314-
region,
315-
GenericKind::Alias(kind, data),
316-
data.def_id,
317-
data.substs,
318-
kind == ty::Opaque,
319-
|ty| match *ty.kind() {
320-
ty::Alias(filter_kind, ty::AliasTy { def_id, substs, .. })
321-
if kind == filter_kind =>
322-
{
323-
(def_id, substs)
324-
}
325-
_ => bug!("expected only projection types from env, not {:?}", ty),
326-
},
327-
);
328-
}
329-
330-
#[instrument(level = "debug", skip(self, filter))]
331-
fn generic_must_outlive(
332-
&mut self,
333-
origin: infer::SubregionOrigin<'tcx>,
334-
region: ty::Region<'tcx>,
335-
generic: GenericKind<'tcx>,
336-
def_id: DefId,
337-
substs: SubstsRef<'tcx>,
338-
is_opaque: bool,
339-
filter: impl Fn(Ty<'tcx>) -> (DefId, SubstsRef<'tcx>),
301+
alias_ty: ty::AliasTy<'tcx>,
340302
) {
341303
// An optimization for a common case with opaque types.
342-
if substs.is_empty() {
304+
if alias_ty.substs.is_empty() {
343305
return;
344306
}
345307

@@ -361,14 +323,14 @@ where
361323
// These are guaranteed to apply, no matter the inference
362324
// results.
363325
let trait_bounds: Vec<_> =
364-
self.verify_bound.declared_region_bounds(def_id, substs).collect();
326+
self.verify_bound.declared_bounds_from_definition(alias_ty).collect();
365327

366328
debug!(?trait_bounds);
367329

368330
// Compute the bounds we can derive from the environment. This
369331
// is an "approximate" match -- in some cases, these bounds
370332
// may not apply.
371-
let mut approx_env_bounds = self.verify_bound.approx_declared_bounds_from_env(generic);
333+
let mut approx_env_bounds = self.verify_bound.approx_declared_bounds_from_env(alias_ty);
372334
debug!(?approx_env_bounds);
373335

374336
// Remove outlives bounds that we get from the environment but
@@ -383,8 +345,8 @@ where
383345
// If the declaration is `trait Trait<'b> { type Item: 'b; }`, then `projection_declared_bounds_from_trait`
384346
// will be invoked with `['b => ^1]` and so we will get `^1` returned.
385347
let bound = bound_outlives.skip_binder();
386-
let (def_id, substs) = filter(bound.0);
387-
self.verify_bound.declared_region_bounds(def_id, substs).all(|r| r != bound.1)
348+
let ty::Alias(_, alias_ty) = bound.0.kind() else { bug!("expected AliasTy") };
349+
self.verify_bound.declared_bounds_from_definition(*alias_ty).all(|r| r != bound.1)
388350
});
389351

390352
// If declared bounds list is empty, the only applicable rule is
@@ -401,12 +363,12 @@ where
401363
// the problem is to add `T: 'r`, which isn't true. So, if there are no
402364
// inference variables, we use a verify constraint instead of adding
403365
// edges, which winds up enforcing the same condition.
404-
let needs_infer = substs.needs_infer();
405-
if approx_env_bounds.is_empty() && trait_bounds.is_empty() && (needs_infer || is_opaque) {
366+
if approx_env_bounds.is_empty()
367+
&& trait_bounds.is_empty()
368+
&& (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque)
369+
{
406370
debug!("no declared bounds");
407-
408-
self.substs_must_outlive(substs, origin, region);
409-
371+
self.substs_must_outlive(alias_ty.substs, origin, region);
410372
return;
411373
}
412374

@@ -447,14 +409,9 @@ where
447409
// projection outlive; in some cases, this may add insufficient
448410
// edges into the inference graph, leading to inference failures
449411
// even though a satisfactory solution exists.
450-
let verify_bound = self.verify_bound.projection_opaque_bounds(
451-
generic,
452-
def_id,
453-
substs,
454-
&mut Default::default(),
455-
);
456-
debug!("projection_must_outlive: pushing {:?}", verify_bound);
457-
self.delegate.push_verify(origin, generic, region, verify_bound);
412+
let verify_bound = self.verify_bound.alias_bound(alias_ty, &mut Default::default());
413+
debug!("alias_must_outlive: pushing {:?}", verify_bound);
414+
self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound);
458415
}
459416

460417
fn substs_must_outlive(

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

+25-37
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::infer::outlives::components::{compute_components_recursive, Component};
22
use crate::infer::outlives::env::RegionBoundPairs;
33
use crate::infer::region_constraints::VerifyIfEq;
4-
use crate::infer::{GenericKind, VerifyBound};
4+
use crate::infer::VerifyBound;
55
use rustc_data_structures::sso::SsoHashSet;
6-
use rustc_hir::def_id::DefId;
76
use rustc_middle::ty::GenericArg;
8-
use rustc_middle::ty::{self, OutlivesPredicate, SubstsRef, Ty, TyCtxt};
7+
use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
98

109
use smallvec::smallvec;
1110

@@ -94,29 +93,26 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
9493
/// this list.
9594
pub fn approx_declared_bounds_from_env(
9695
&self,
97-
generic: GenericKind<'tcx>,
96+
alias_ty: ty::AliasTy<'tcx>,
9897
) -> Vec<ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>> {
99-
let projection_ty = generic.to_ty(self.tcx);
100-
let erased_projection_ty = self.tcx.erase_regions(projection_ty);
101-
self.declared_generic_bounds_from_env_for_erased_ty(erased_projection_ty)
98+
let erased_alias_ty = self.tcx.erase_regions(alias_ty.to_ty(self.tcx));
99+
self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty)
102100
}
103101

104102
#[instrument(level = "debug", skip(self, visited))]
105-
pub fn projection_opaque_bounds(
103+
pub fn alias_bound(
106104
&self,
107-
generic: GenericKind<'tcx>,
108-
def_id: DefId,
109-
substs: SubstsRef<'tcx>,
105+
alias_ty: ty::AliasTy<'tcx>,
110106
visited: &mut SsoHashSet<GenericArg<'tcx>>,
111107
) -> VerifyBound<'tcx> {
112-
let generic_ty = generic.to_ty(self.tcx);
108+
let alias_ty_as_ty = alias_ty.to_ty(self.tcx);
113109

114110
// Search the env for where clauses like `P: 'a`.
115-
let projection_opaque_bounds = self
116-
.approx_declared_bounds_from_env(generic)
111+
let env_bounds = self
112+
.approx_declared_bounds_from_env(alias_ty)
117113
.into_iter()
118114
.map(|binder| {
119-
if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() && ty == generic_ty {
115+
if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() && ty == alias_ty_as_ty {
120116
// Micro-optimize if this is an exact match (this
121117
// occurs often when there are no region variables
122118
// involved).
@@ -126,19 +122,19 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
126122
VerifyBound::IfEq(verify_if_eq_b)
127123
}
128124
});
129-
// Extend with bounds that we can find from the trait.
130-
let trait_bounds =
131-
self.declared_region_bounds(def_id, substs).map(|r| VerifyBound::OutlivedBy(r));
125+
126+
// Extend with bounds that we can find from the definition.
127+
let definition_bounds =
128+
self.declared_bounds_from_definition(alias_ty).map(|r| VerifyBound::OutlivedBy(r));
132129

133130
// see the extensive comment in projection_must_outlive
134131
let recursive_bound = {
135132
let mut components = smallvec![];
136-
compute_components_recursive(self.tcx, generic_ty.into(), &mut components, visited);
133+
compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited);
137134
self.bound_from_components(&components, visited)
138135
};
139136

140-
VerifyBound::AnyBound(projection_opaque_bounds.chain(trait_bounds).collect())
141-
.or(recursive_bound)
137+
VerifyBound::AnyBound(env_bounds.chain(definition_bounds).collect()).or(recursive_bound)
142138
}
143139

144140
fn bound_from_components(
@@ -149,10 +145,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
149145
let mut bounds = components
150146
.iter()
151147
.map(|component| self.bound_from_single_component(component, visited))
152-
.filter(|bound| {
153-
// Remove bounds that must hold, since they are not interesting.
154-
!bound.must_hold()
155-
});
148+
// Remove bounds that must hold, since they are not interesting.
149+
.filter(|bound| !bound.must_hold());
156150

157151
match (bounds.next(), bounds.next()) {
158152
(Some(first), None) => first,
@@ -170,13 +164,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
170164
match *component {
171165
Component::Region(lt) => VerifyBound::OutlivedBy(lt),
172166
Component::Param(param_ty) => self.param_bound(param_ty),
173-
Component::Alias(kind, data) => self.projection_opaque_bounds(
174-
GenericKind::Alias(kind, data),
175-
data.def_id,
176-
data.substs,
177-
visited,
178-
),
179-
Component::EscapingProjection(ref components) => {
167+
Component::Alias(alias_ty) => self.alias_bound(alias_ty, visited),
168+
Component::EscapingAlias(ref components) => {
180169
self.bound_from_components(components, visited)
181170
}
182171
Component::UnresolvedInferenceVariable(v) => {
@@ -292,16 +281,15 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
292281
///
293282
/// This is for simplicity, and because we are not really smart
294283
/// enough to cope with such bounds anywhere.
295-
pub fn declared_region_bounds(
284+
pub fn declared_bounds_from_definition(
296285
&self,
297-
def_id: DefId,
298-
substs: SubstsRef<'tcx>,
286+
alias_ty: ty::AliasTy<'tcx>,
299287
) -> impl Iterator<Item = ty::Region<'tcx>> {
300288
let tcx = self.tcx;
301-
let bounds = tcx.item_bounds(def_id);
289+
let bounds = tcx.item_bounds(alias_ty.def_id);
302290
trace!("{:#?}", bounds.0);
303291
bounds
304-
.subst_iter(tcx, substs)
292+
.subst_iter(tcx, alias_ty.substs)
305293
.filter_map(|p| p.to_opt_type_outlives())
306294
.filter_map(|p| p.no_bound_vars())
307295
.map(|OutlivesPredicate(_, r)| r)

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

+4-10
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub struct Verify<'tcx> {
167167
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
168168
pub enum GenericKind<'tcx> {
169169
Param(ty::ParamTy),
170-
Alias(ty::AliasKind, ty::AliasTy<'tcx>),
170+
Alias(ty::AliasTy<'tcx>),
171171
}
172172

173173
/// Describes the things that some `GenericKind` value `G` is known to
@@ -746,10 +746,7 @@ impl<'tcx> fmt::Debug for GenericKind<'tcx> {
746746
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
747747
match *self {
748748
GenericKind::Param(ref p) => write!(f, "{:?}", p),
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()))
752-
}),
749+
GenericKind::Alias(ref p) => write!(f, "{:?}", p),
753750
}
754751
}
755752
}
@@ -758,10 +755,7 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
758755
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
759756
match *self {
760757
GenericKind::Param(ref p) => write!(f, "{}", p),
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()))
764-
}),
758+
GenericKind::Alias(ref p) => write!(f, "{}", p),
765759
}
766760
}
767761
}
@@ -770,7 +764,7 @@ impl<'tcx> GenericKind<'tcx> {
770764
pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
771765
match *self {
772766
GenericKind::Param(ref p) => p.to_ty(tcx),
773-
GenericKind::Alias(kind, data) => tcx.mk_ty(ty::Alias(kind, data)),
767+
GenericKind::Alias(ref p) => p.to_ty(tcx),
774768
}
775769
}
776770
}

‎compiler/rustc_infer/src/traits/util.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,15 @@ impl<'tcx> Elaborator<'tcx> {
261261

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

264-
Component::Alias(kind, data) => {
265-
let ty = tcx.mk_ty(ty::Alias(kind, data));
264+
Component::Alias(alias_ty) => {
265+
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
266+
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
266267
Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
267-
ty::OutlivesPredicate(ty, r_min),
268+
ty::OutlivesPredicate(alias_ty.to_ty(tcx), r_min),
268269
)))
269270
}
270271

271-
Component::EscapingProjection(_) => {
272+
Component::EscapingAlias(_) => {
272273
// We might be able to do more here, but we don't
273274
// want to deal with escaping vars right now.
274275
None

‎compiler/rustc_middle/src/traits/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,5 +213,5 @@ pub struct NormalizationResult<'tcx> {
213213
pub enum OutlivesBound<'tcx> {
214214
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
215215
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
216-
RegionSubAlias(ty::Region<'tcx>, ty::AliasKind, ty::AliasTy<'tcx>),
216+
RegionSubAlias(ty::Region<'tcx>, ty::AliasTy<'tcx>),
217217
}

‎compiler/rustc_middle/src/ty/sty.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1245,19 +1245,34 @@ pub struct AliasTy<'tcx> {
12451245
/// aka. `tcx.parent(def_id)`.
12461246
pub def_id: DefId,
12471247

1248-
/// This field exists to prevent the creation of `ProjectionTy` without using
1248+
/// This field exists to prevent the creation of `AliasTy` without using
12491249
/// [TyCtxt::mk_alias_ty].
12501250
pub(super) _use_mk_alias_ty_instead: (),
12511251
}
12521252

1253+
impl<'tcx> AliasTy<'tcx> {
1254+
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
1255+
match tcx.def_kind(self.def_id) {
1256+
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
1257+
DefKind::OpaqueTy => ty::Opaque,
1258+
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
1259+
}
1260+
}
1261+
1262+
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
1263+
tcx.mk_ty(ty::Alias(self.kind(tcx), self))
1264+
}
1265+
}
1266+
1267+
/// The following methods work only with associated type projections.
12531268
impl<'tcx> AliasTy<'tcx> {
12541269
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
12551270
match tcx.def_kind(self.def_id) {
12561271
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
12571272
DefKind::ImplTraitPlaceholder => {
12581273
tcx.parent(tcx.impl_trait_in_trait_parent(self.def_id))
12591274
}
1260-
kind => bug!("unexpected DefKind in ProjectionTy: {kind:?}"),
1275+
kind => bug!("expected a projection AliasTy; found {kind:?}"),
12611276
}
12621277
}
12631278

‎compiler/rustc_traits/src/implied_outlives_bounds.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -154,10 +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::Alias(kind, p) => {
158-
Some(OutlivesBound::RegionSubAlias(sub_region, kind, p))
159-
}
160-
Component::EscapingProjection(_) =>
157+
Component::Alias(p) => Some(OutlivesBound::RegionSubAlias(sub_region, p)),
158+
Component::EscapingAlias(_) =>
161159
// If the projection has escaping regions, don't
162160
// try to infer any implied bounds even for its
163161
// free components. This is conservative, because
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Here we process outlive obligations involving
2+
// opaque types with bound vars in substs.
3+
// This was an ICE.
4+
//
5+
// check-pass
6+
#![feature(type_alias_impl_trait)]
7+
8+
type Ty<'a> = impl Sized + 'a;
9+
fn define<'a>() -> Ty<'a> {}
10+
11+
// Ty<'^0>: 'static
12+
fn test1(_: &'static fn(Ty<'_>)) {}
13+
14+
fn test2() {
15+
None::<&fn(Ty<'_>)>;
16+
}
17+
18+
fn main() { }

0 commit comments

Comments
 (0)
Please sign in to comment.