diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index c99eb12efcca2..5c6629d8b3db8 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -312,7 +312,7 @@ fn check_explicit_predicates<'tcx>( } } -/// Check the inferred predicates declared on the type. +/// Check the inferred predicates of the type. /// /// ### Example /// diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0759fa3da428a..665e919e23cb2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -180,6 +180,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.sess.threads() > 1 } + fn expand_free_alias_tys>>(self, t: T) -> T { + self.expand_free_alias_tys(t) + } + fn expand_abstract_consts>>(self, t: T) -> T { self.expand_abstract_consts(t) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6fe5927c29fcb..1954c02f26204 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -916,7 +916,7 @@ impl<'tcx> TyCtxt<'tcx> { value.fold_with(&mut FreeAliasTypeExpander { tcx: self, depth: 0 }) } - /// Peel off all [free alias types] in this type until there are none left. + /// Peel off all [free alias types][free] in this type until there are none left. /// /// This only expands free alias types in “head” / outermost positions. It can /// be used over [expand_free_alias_tys] as an optimization in situations where diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 0fd2d9f3ad38b..49413ee2bbd65 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -149,6 +149,7 @@ pub trait Interner: fn evaluation_is_concurrent(&self) -> bool; + fn expand_free_alias_tys>(self, t: T) -> T; fn expand_abstract_consts>(self, t: T) -> T; type GenericsOf: GenericsOf; diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index b09a378d34143..7ccdcec93034a 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -58,6 +58,7 @@ pub fn push_outlives_components( ty: I::Ty, out: &mut SmallVec<[Component; 4]>, ) { + let ty = cx.expand_free_alias_tys(ty); ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() }); } @@ -140,6 +141,9 @@ impl TypeVisitor for OutlivesCollector<'_, I> { self.out.push(Component::Placeholder(p)); } + // All free alias types should've been expanded beforehand. + ty::Alias(ty::Free, _) => panic!("unexpected free alias type"), + // For projections, we prefer to generate an obligation like // `>::Foo: 'a`, because this gives the // regionck more ways to prove that it holds. However, diff --git a/tests/ui/lazy-type-alias/implied-outlives-bounds-1.print.stderr b/tests/ui/lazy-type-alias/implied-outlives-bounds-1.print.stderr new file mode 100644 index 0000000000000..6fa9aa0a3a7aa --- /dev/null +++ b/tests/ui/lazy-type-alias/implied-outlives-bounds-1.print.stderr @@ -0,0 +1,11 @@ +error: rustc_outlives + --> $DIR/implied-outlives-bounds-1.rs:16:1 + | +LL | struct Type<'a, K, V>(&'a mut Alias); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: K: 'a + = note: V: 'a + +error: aborting due to 1 previous error + diff --git a/tests/ui/lazy-type-alias/implied-outlives-bounds-1.rs b/tests/ui/lazy-type-alias/implied-outlives-bounds-1.rs new file mode 100644 index 0000000000000..a15bef0085ca5 --- /dev/null +++ b/tests/ui/lazy-type-alias/implied-outlives-bounds-1.rs @@ -0,0 +1,17 @@ +// Check that we infer the outlives-predicates `K: 'a`, `V: 'a` for `Type` +// from the free alias `Alias`. +// FIXME(fmease): Proper explainer. + +//@ revisions: default print +//@[default] check-pass + +#![feature(lazy_type_alias)] +#![cfg_attr(print, feature(rustc_attrs))] +#![allow(incomplete_features)] + +#[cfg_attr(print, rustc_outlives)] +struct Type<'a, K, V>(&'a mut Alias); //[print]~ ERROR rustc_outlives + +type Alias = (K, V); + +fn main() {}