Skip to content

Commit 52fa23a

Browse files
committed
Auto merge of #71218 - eddyb:a-lifetime-stranded-in-fn-def, r=nikomatsakis
outlives: ignore lifetimes shallowly found in `ty::FnDef`s. Fixes #70917 by restoring the pre-#70164 behavior for now. r? @nikomatsakis
2 parents 339a938 + f86f032 commit 52fa23a

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

src/librustc_infer/infer/outlives/verify.rs

+25
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,31 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
4242
match ty.kind {
4343
ty::Param(p) => self.param_bound(p),
4444
ty::Projection(data) => self.projection_bound(data),
45+
ty::FnDef(_, substs) => {
46+
// HACK(eddyb) ignore lifetimes found shallowly in `substs`.
47+
// This is inconsistent with `ty::Adt` (including all substs),
48+
// but consistent with previous (accidental) behavior.
49+
// See https://github.com/rust-lang/rust/issues/70917
50+
// for further background and discussion.
51+
let mut bounds = substs
52+
.iter()
53+
.filter_map(|&child| match child.unpack() {
54+
GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
55+
GenericArgKind::Lifetime(_) => None,
56+
GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
57+
})
58+
.filter(|bound| {
59+
// Remove bounds that must hold, since they are not interesting.
60+
!bound.must_hold()
61+
});
62+
63+
match (bounds.next(), bounds.next()) {
64+
(Some(first), None) => first,
65+
(first, second) => VerifyBound::AllBounds(
66+
first.into_iter().chain(second).chain(bounds).collect(),
67+
),
68+
}
69+
}
4570
_ => self.recursive_bound(ty.into()),
4671
}
4772
}

src/librustc_middle/ty/outlives.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
6262
// in the `subtys` iterator (e.g., when encountering a
6363
// projection).
6464
match ty.kind {
65+
ty::FnDef(_, substs) => {
66+
// HACK(eddyb) ignore lifetimes found shallowly in `substs`.
67+
// This is inconsistent with `ty::Adt` (including all substs)
68+
// and with `ty::Closure` (ignoring all substs other than
69+
// upvars, of which a `ty::FnDef` doesn't have any), but
70+
// consistent with previous (accidental) behavior.
71+
// See https://github.com/rust-lang/rust/issues/70917
72+
// for further background and discussion.
73+
for &child in substs {
74+
match child.unpack() {
75+
GenericArgKind::Type(ty) => {
76+
compute_components(tcx, ty, out);
77+
}
78+
GenericArgKind::Lifetime(_) => {}
79+
GenericArgKind::Const(_) => {
80+
compute_components_recursive(tcx, child, out);
81+
}
82+
}
83+
}
84+
}
85+
6586
ty::Closure(_, ref substs) => {
6687
for upvar_ty in substs.as_closure().upvar_tys() {
6788
compute_components(tcx, upvar_ty, out);
@@ -136,23 +157,22 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
136157
ty::Float(..) | // OutlivesScalar
137158
ty::Never | // ...
138159
ty::Adt(..) | // OutlivesNominalType
139-
ty::Opaque(..) | // OutlivesNominalType (ish)
160+
ty::Opaque(..) | // OutlivesNominalType (ish)
140161
ty::Foreign(..) | // OutlivesNominalType
141162
ty::Str | // OutlivesScalar (ish)
142163
ty::Array(..) | // ...
143164
ty::Slice(..) | // ...
144165
ty::RawPtr(..) | // ...
145166
ty::Ref(..) | // OutlivesReference
146167
ty::Tuple(..) | // ...
147-
ty::FnDef(..) | // OutlivesFunction (*)
148168
ty::FnPtr(_) | // OutlivesFunction (*)
149-
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
169+
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
150170
ty::Placeholder(..) |
151171
ty::Bound(..) |
152172
ty::Error => {
153-
// (*) Bare functions and traits are both binders. In the
154-
// RFC, this means we would add the bound regions to the
155-
// "bound regions list". In our representation, no such
173+
// (*) Function pointers and trait objects are both binders.
174+
// In the RFC, this means we would add the bound regions to
175+
// the "bound regions list". In our representation, no such
156176
// list is maintained explicitly, because bound regions
157177
// themselves can be readily identified.
158178
compute_components_recursive(tcx, ty.into(), out);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// check-pass
2+
3+
fn assert_static<T: 'static>(_: T) {}
4+
5+
// NOTE(eddyb) the `'a: 'a` may look a bit strange, but we *really* want
6+
// `'a` to be an *early-bound* parameter, otherwise it doesn't matter anyway.
7+
fn capture_lifetime<'a: 'a>() {}
8+
9+
fn test_lifetime<'a>() {
10+
assert_static(capture_lifetime::<'a>);
11+
}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)