Skip to content

Commit c5165ba

Browse files
committed
Treat weak alias types more like ADTs when computing implied bounds
1 parent af69f4c commit c5165ba

File tree

8 files changed

+55
-61
lines changed

8 files changed

+55
-61
lines changed

compiler/rustc_hir_analysis/src/outlives/utils.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
2121
) {
2222
// If the `'a` region is bound within the field type itself, we
2323
// don't want to propagate this constraint to the header.
24-
if !is_free_region(outlived_region) {
24+
if !is_early_bound_region(outlived_region) {
2525
return;
2626
}
2727

@@ -132,7 +132,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
132132
}
133133

134134
GenericArgKind::Lifetime(r) => {
135-
if !is_free_region(r) {
135+
if !is_early_bound_region(r) {
136136
return;
137137
}
138138
required_predicates.entry(ty::OutlivesPredicate(kind, outlived_region)).or_insert(span);
@@ -144,7 +144,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
144144
}
145145
}
146146

147-
fn is_free_region(region: Region<'_>) -> bool {
147+
fn is_early_bound_region(region: Region<'_>) -> bool {
148148
// First, screen for regions that might appear in a type header.
149149
match *region {
150150
// These correspond to `T: 'a` relationships:

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

+17-16
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ fn compute_components<'tcx>(
138138
// trait-ref. Therefore, if we see any higher-ranked regions,
139139
// we simply fallback to the most restrictive rule, which
140140
// requires that `Pi: 'a` for all `i`.
141-
ty::Alias(_, alias_ty) => {
141+
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, alias_ty) => {
142142
if !alias_ty.has_escaping_bound_vars() {
143143
// best case: no escaping regions, so push the
144144
// projection and skip the subtree (thus generating no
@@ -171,21 +171,22 @@ fn compute_components<'tcx>(
171171
// the type and then visits the types that are lexically
172172
// contained within. (The comments refer to relevant rules
173173
// from RFC1214.)
174-
ty::Bool | // OutlivesScalar
175-
ty::Char | // OutlivesScalar
176-
ty::Int(..) | // OutlivesScalar
177-
ty::Uint(..) | // OutlivesScalar
178-
ty::Float(..) | // OutlivesScalar
179-
ty::Never | // ...
180-
ty::Adt(..) | // OutlivesNominalType
181-
ty::Foreign(..) | // OutlivesNominalType
182-
ty::Str | // OutlivesScalar (ish)
183-
ty::Slice(..) | // ...
184-
ty::RawPtr(..) | // ...
185-
ty::Ref(..) | // OutlivesReference
186-
ty::Tuple(..) | // ...
187-
ty::FnPtr(_) | // OutlivesFunction (*)
188-
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
174+
ty::Bool | // OutlivesScalar
175+
ty::Char | // OutlivesScalar
176+
ty::Int(..) | // OutlivesScalar
177+
ty::Uint(..) | // OutlivesScalar
178+
ty::Float(..) | // OutlivesScalar
179+
ty::Never | // ...
180+
ty::Adt(..) | // OutlivesNominalType
181+
ty::Alias(ty::Weak, _) | // OutlivesNominalType (ish)
182+
ty::Foreign(..) | // OutlivesNominalType
183+
ty::Str | // OutlivesScalar (ish)
184+
ty::Slice(..) | // ...
185+
ty::RawPtr(..) | // ...
186+
ty::Ref(..) | // OutlivesReference
187+
ty::Tuple(..) | // ...
188+
ty::FnPtr(_) | // OutlivesFunction (*)
189+
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
189190
ty::Bound(..) |
190191
ty::Error(_) => {
191192
// (*) Function pointers and trait objects are both binders.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: rustc_outlives
2+
--> $DIR/implied-outlives-bounds-1.rs:16:1
3+
|
4+
LL | struct Type<'a, K, V>(&'a mut Alias<K, V>);
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: K: 'a
8+
= note: V: 'a
9+
10+
error: aborting due to 1 previous error
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Check that we infer the outlives-predicates `K: 'a`, `V: 'a` for `Type`
2+
// from the weak alias `Alias`.
3+
// This mirrors the behavior of ADTs instead of other kinds of alias types
4+
// like projections and opaque types.
5+
// If we were to mirror the semantics of the latter, we would infer the
6+
// outlives-predicate `Alias<K, V>: 'a` instead which is not what we want.
7+
8+
//@ revisions: default print
9+
//@[default] check-pass
10+
11+
#![feature(lazy_type_alias)]
12+
#![cfg_attr(print, feature(rustc_attrs))]
13+
#![allow(incomplete_features)]
14+
15+
#[cfg_attr(print, rustc_outlives)]
16+
struct Type<'a, K, V>(&'a mut Alias<K, V>); //[print]~ ERROR rustc_outlives
17+
18+
type Alias<K, V> = (K, V);
19+
20+
fn main() {}

tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs

-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ mod test_lifetime_param {
55
fn defining(a: &str) -> Ty<'_> { a }
66
fn assert_static<'a: 'static>() {}
77
fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
8-
//~^ ERROR: lifetime may not live long enough
98
}
109

1110
mod test_higher_kinded_lifetime_param {
@@ -27,7 +26,6 @@ mod test_type_param {
2726
fn defining<A>(s: A) -> Ty<A> { s }
2827
fn assert_static<A: 'static>() {}
2928
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
30-
//~^ ERROR: parameter type `A` may not live long enough
3129
}
3230

3331
mod test_implied_from_fn_sig {
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,16 @@
11
error: lifetime may not live long enough
2-
--> $DIR/implied_lifetime_wf_check3.rs:7:43
3-
|
4-
LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
5-
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
6-
7-
error: lifetime may not live long enough
8-
--> $DIR/implied_lifetime_wf_check3.rs:15:46
2+
--> $DIR/implied_lifetime_wf_check3.rs:14:46
93
|
104
LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
115
| -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
126

137
error: lifetime may not live long enough
14-
--> $DIR/implied_lifetime_wf_check3.rs:21:21
8+
--> $DIR/implied_lifetime_wf_check3.rs:20:21
159
|
1610
LL | fn test<'a>() { assert_static::<'a>() }
1711
| -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
1812
| |
1913
| lifetime `'a` defined here
2014

21-
error[E0310]: the parameter type `A` may not live long enough
22-
--> $DIR/implied_lifetime_wf_check3.rs:29:41
23-
|
24-
LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
25-
| ^^^^^^^^^^^^^^^^^^
26-
| |
27-
| the parameter type `A` must be valid for the static lifetime...
28-
| ...so that the type `A` will meet its required lifetime bounds
29-
|
30-
help: consider adding an explicit lifetime bound
31-
|
32-
LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
33-
| +++++++++
34-
35-
error: aborting due to 4 previous errors
15+
error: aborting due to 2 previous errors
3616

37-
For more information about this error, try `rustc --explain E0310`.

tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mod test_type_param_static {
66
fn defining<A: 'static>(s: A) -> Ty<A> { s }
77
fn assert_static<A: 'static>() {}
88
fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
9-
//~^ ERROR: the parameter type `A` may not live long enough
109
}
1110

1211
fn main() {}

tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr

+1-15
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,6 @@ help: consider adding an explicit lifetime bound
1212
LL | type Ty<A: 'static> = impl Sized + 'static;
1313
| +++++++++
1414

15-
error[E0310]: the parameter type `A` may not live long enough
16-
--> $DIR/implied_lifetime_wf_check4_static.rs:8:41
17-
|
18-
LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
19-
| ^^^^^^^^^^^^^^^^^^
20-
| |
21-
| the parameter type `A` must be valid for the static lifetime...
22-
| ...so that the type `A` will meet its required lifetime bounds
23-
|
24-
help: consider adding an explicit lifetime bound
25-
|
26-
LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
27-
| +++++++++
28-
29-
error: aborting due to 2 previous errors
15+
error: aborting due to 1 previous error
3016

3117
For more information about this error, try `rustc --explain E0310`.

0 commit comments

Comments
 (0)