Skip to content

Commit 0e7952c

Browse files
committed
Treat weak alias types more like ADTs when computing implied bounds
1 parent 5a0a5e6 commit 0e7952c

9 files changed

+41
-50
lines changed

compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ fn check_explicit_predicates<'tcx>(
299299
}
300300
}
301301

302-
/// Check the inferred predicates declared on the type.
302+
/// Check the inferred predicates of the type.
303303
///
304304
/// ### Example
305305
///

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_type_ir/src/outlives.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
148148
// trait-ref. Therefore, if we see any higher-ranked regions,
149149
// we simply fallback to the most restrictive rule, which
150150
// requires that `Pi: 'a` for all `i`.
151-
ty::Alias(_, alias_ty) => {
151+
ty::Alias(ty::Projection | ty::Opaque | ty::Inherent, alias_ty) => {
152152
if !alias_ty.has_escaping_bound_vars() {
153153
// best case: no escaping regions, so push the
154154
// projection and skip the subtree (thus generating no
@@ -195,6 +195,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
195195
}
196196

197197
ty::Adt(_, _)
198+
| ty::Alias(ty::Weak, _)
198199
| ty::Foreign(_)
199200
| ty::Array(_, _)
200201
| ty::Pat(_, _)
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
@@ -12,7 +12,6 @@ where
1212
test_lifetime_param::Ty<'a>: 'static,
1313
{
1414
test_lifetime_param::assert_static::<'a>()
15-
//~^ ERROR: lifetime may not live long enough
1615
}
1716

1817
mod test_higher_kinded_lifetime_param {
@@ -50,7 +49,6 @@ where
5049
test_type_param::Ty<A>: 'static,
5150
{
5251
test_type_param::assert_static::<A>()
53-
//~^ ERROR: parameter type `A` may not live long enough
5452
}
5553

5654
mod test_implied_from_fn_sig {
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
error: lifetime may not live long enough
2-
--> $DIR/implied_lifetime_wf_check3.rs:14:5
3-
|
4-
LL | fn test_lifetime_param_test<'a>()
5-
| -- lifetime `'a` defined here
6-
...
7-
LL | test_lifetime_param::assert_static::<'a>()
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
9-
10-
error: lifetime may not live long enough
11-
--> $DIR/implied_lifetime_wf_check3.rs:29:5
2+
--> $DIR/implied_lifetime_wf_check3.rs:28:5
123
|
134
LL | fn test_higher_kinded_lifetime_param_test<'a>()
145
| -- lifetime `'a` defined here
@@ -17,27 +8,12 @@ LL | test_higher_kinded_lifetime_param::assert_static::<'a>()
178
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
189

1910
error: lifetime may not live long enough
20-
--> $DIR/implied_lifetime_wf_check3.rs:36:9
11+
--> $DIR/implied_lifetime_wf_check3.rs:35:9
2112
|
2213
LL | fn test<'a>() {
2314
| -- lifetime `'a` defined here
2415
LL | assert_static::<'a>()
2516
| ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
2617

27-
error[E0310]: the parameter type `A` may not live long enough
28-
--> $DIR/implied_lifetime_wf_check3.rs:52:5
29-
|
30-
LL | test_type_param::assert_static::<A>()
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32-
| |
33-
| the parameter type `A` must be valid for the static lifetime...
34-
| ...so that the type `A` will meet its required lifetime bounds
35-
|
36-
help: consider adding an explicit lifetime bound
37-
|
38-
LL | fn test_type_param_test<A: 'static>()
39-
| +++++++++
40-
41-
error: aborting due to 4 previous errors
18+
error: aborting due to 2 previous errors
4219

43-
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
@@ -15,7 +15,6 @@ where
1515
Ty<A>: 'static,
1616
{
1717
assert_static::<A>()
18-
//~^ ERROR: the parameter type `A` may not live long enough
1918
}
2019

2120
fn main() {}

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

+1-15
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,6 @@ help: consider adding an explicit lifetime bound
1717
LL | pub type Ty<A: 'static> = impl Sized + 'static;
1818
| +++++++++
1919

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

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

0 commit comments

Comments
 (0)