Skip to content

Commit 118c6c1

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

File tree

4 files changed

+51
-19
lines changed

4 files changed

+51
-19
lines changed

compiler/rustc_hir_analysis/src/outlives/utils.rs

Lines changed: 3 additions & 3 deletions
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

Lines changed: 17 additions & 16 deletions
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.
Lines changed: 11 additions & 0 deletions
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+
Lines changed: 20 additions & 0 deletions
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() {}

0 commit comments

Comments
 (0)