Skip to content

Commit 91783b9

Browse files
committed
Expand free alias types when computing implied outlives-bounds
1 parent 414482f commit 91783b9

File tree

7 files changed

+39
-2
lines changed

7 files changed

+39
-2
lines changed

compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ fn check_explicit_predicates<'tcx>(
312312
}
313313
}
314314

315-
/// Check the inferred predicates declared on the type.
315+
/// Check the inferred predicates of the type.
316316
///
317317
/// ### Example
318318
///

compiler/rustc_middle/src/ty/context.rs

+4
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
180180
self.sess.threads() > 1
181181
}
182182

183+
fn expand_free_alias_tys<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
184+
self.expand_free_alias_tys(t)
185+
}
186+
183187
fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
184188
self.expand_abstract_consts(t)
185189
}

compiler/rustc_middle/src/ty/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ impl<'tcx> TyCtxt<'tcx> {
916916
value.fold_with(&mut FreeAliasTypeExpander { tcx: self, depth: 0 })
917917
}
918918

919-
/// Peel off all [free alias types] in this type until there are none left.
919+
/// Peel off all [free alias types][free] in this type until there are none left.
920920
///
921921
/// This only expands free alias types in “head” / outermost positions. It can
922922
/// be used over [expand_free_alias_tys] as an optimization in situations where

compiler/rustc_type_ir/src/interner.rs

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub trait Interner:
149149

150150
fn evaluation_is_concurrent(&self) -> bool;
151151

152+
fn expand_free_alias_tys<T: TypeFoldable<Self>>(self, t: T) -> T;
152153
fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
153154

154155
type GenericsOf: GenericsOf<Self>;

compiler/rustc_type_ir/src/outlives.rs

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub fn push_outlives_components<I: Interner>(
5858
ty: I::Ty,
5959
out: &mut SmallVec<[Component<I>; 4]>,
6060
) {
61+
let ty = cx.expand_free_alias_tys(ty);
6162
ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() });
6263
}
6364

@@ -140,6 +141,9 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
140141
self.out.push(Component::Placeholder(p));
141142
}
142143

144+
// All free alias types should've been expanded beforehand.
145+
ty::Alias(ty::Free, _) => panic!("unexpected free alias type"),
146+
143147
// For projections, we prefer to generate an obligation like
144148
// `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
145149
// regionck more ways to prove that it holds. However,
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,17 @@
1+
// Check that we infer the outlives-predicates `K: 'a`, `V: 'a` for `Type`
2+
// from the free alias `Alias`.
3+
// FIXME(fmease): Proper explainer.
4+
5+
//@ revisions: default print
6+
//@[default] check-pass
7+
8+
#![feature(lazy_type_alias)]
9+
#![cfg_attr(print, feature(rustc_attrs))]
10+
#![allow(incomplete_features)]
11+
12+
#[cfg_attr(print, rustc_outlives)]
13+
struct Type<'a, K, V>(&'a mut Alias<K, V>); //[print]~ ERROR rustc_outlives
14+
15+
type Alias<K, V> = (K, V);
16+
17+
fn main() {}

0 commit comments

Comments
 (0)