handle trait objects formed from traits with Self::Foo: 'a clauses

This commit is contained in:
Niko Matsakis 2018-11-16 08:58:55 -05:00
parent 0d744ec6ec
commit 6575988d8e
2 changed files with 33 additions and 5 deletions
src
librustc_typeck/outlives
test/ui/rfc-2093-infer-outlives

View File

@ -14,6 +14,7 @@ use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::fold::TypeFoldable;
use rustc::util::nodemap::FxHashMap;
use super::explicit::ExplicitPredicatesMap;
@ -311,13 +312,23 @@ pub fn check_explicit_predicates<'tcx>(
//
// Note that we do this check for self **before** applying `substs`. In the
// case that `substs` come from a `dyn Trait` type, our caller will have
// included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
// included `Self = usize` as the value for `Self`. If we were
// to apply the substs, and not filter this predicate, we might then falsely
// conclude that e.g. `X: 'x` was a reasonable inferred requirement.
if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
if ty.is_self() && ignore_self_ty.0 {
debug!("skipping self ty = {:?}", &ty);
continue;
//
// Another similar case is where we have a inferred
// requirement like `<Self as Trait>::Foo: 'b`. We presently
// ignore such requirements as well (cc #54467)-- though
// conceivably it might be better if we could extract the `Foo
// = X` binding from the object type (there must be such a
// binding) and thus infer an outlives requirement that `X:
// 'b`.
if ignore_self_ty.0 {
if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
if ty.has_self_ty() {
debug!("skipping self ty = {:?}", &ty);
continue;
}
}
}

View File

@ -0,0 +1,17 @@
// Regression test for #54467:
//
// Here, the trait object has an "inferred outlives" requirement that
// `<Self as MyIterator<'a>>::Item: 'a`; but since we don't know what
// `Self` is, we were (incorrectly) messing things up, leading to
// strange errors. This test ensures that we do not give compilation
// errors.
//
// compile-pass
trait MyIterator<'a>: Iterator where Self::Item: 'a { }
struct MyStruct<'a, A> {
item: Box<dyn MyIterator<'a, Item = A>>
}
fn main() { }