From 5f3e8c797e48e06a9648a7366b89bafa8be835a3 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Wed, 25 Sep 2019 01:02:41 -0500 Subject: [PATCH] Fix GAT lifetime bounds This makes GAT lifetimes late-bound regions --- src/librustc/middle/resolve_lifetime.rs | 4 ++-- src/librustc_typeck/astconv.rs | 6 +++--- .../lifetime_bound.rs | 17 +++++++++++++++++ .../lifetime_bound.stderr | 8 ++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/rfc1598-generic-associated-types/lifetime_bound.rs create mode 100644 src/test/ui/rfc1598-generic-associated-types/lifetime_bound.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d833a34385b2d..3da884c04f26c 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -790,12 +790,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } Type(ref bounds, ref ty) => { let generics = &trait_item.generics; - let mut index = self.next_early_index(); + let index = self.next_early_index(); debug!("visit_ty: index = {}", index); let mut non_lifetime_count = 0; let lifetimes = generics.params.iter().filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::early(&self.tcx.hir(), &mut index, param)) + Some(Region::late(&self.tcx.hir(), param)) } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 718d12484f741..2293519e3519e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2450,11 +2450,11 @@ impl<'tcx> Bounds<'tcx> { sized_predicate.into_iter().chain( self.region_bounds.iter().map(|&(region_bound, span)| { - // Account for the binder being introduced below; no need to shift `param_ty` - // because, at present at least, it can only refer to early-bound regions. let region_bound = ty::fold::shift_region(tcx, region_bound, 1); + // Because of GAT bounds, param_ty may have late-bound regions. + let param_ty = ty::fold::shift_vars(tcx, ¶m_ty, 1); let outlives = ty::OutlivesPredicate(param_ty, region_bound); - (ty::Binder::dummy(outlives).to_predicate(), span) + (ty::Binder::bind(outlives).to_predicate(), span) }).chain( self.trait_bounds.iter().map(|&(bound_trait_ref, span)| { (bound_trait_ref.to_predicate(), span) diff --git a/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.rs b/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.rs new file mode 100644 index 0000000000000..71fd3f83749bf --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.rs @@ -0,0 +1,17 @@ +// check-pass + +// rust-lang/rust#62521: Do not ICE when a generic lifetime is used +// in the type's bound. + +#![feature(generic_associated_types)] +//~^ WARNING the feature `generic_associated_types` is incomplete + +trait Foo { + type PublicKey<'a>: From<&'a [u8]>; +} + +trait Bar { + type Item<'a>: 'a; +} + +fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.stderr b/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.stderr new file mode 100644 index 0000000000000..a20ecc74f2cac --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/lifetime_bound.stderr @@ -0,0 +1,8 @@ +warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash + --> $DIR/lifetime_bound.rs:6:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default +