diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 101edac04c7d4..30e304375fe0e 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -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 `::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; + } } } diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs new file mode 100644 index 0000000000000..438923e29246c --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs @@ -0,0 +1,17 @@ +// Regression test for #54467: +// +// Here, the trait object has an "inferred outlives" requirement that +// `>::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> +} + +fn main() { }