From 0d744ec6eca622aa63bb89f02e819e4270fa5794 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 16 Nov 2018 08:25:46 -0500 Subject: [PATCH 1/2] improve debug output related to bound calculation --- src/librustc/traits/mod.rs | 7 ++++++- src/librustc_typeck/collect.rs | 11 +++++++++++ src/librustc_typeck/outlives/implicit_infer.rs | 17 +++++++++++++---- src/librustc_typeck/outlives/mod.rs | 3 +++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 33b689c60a118..8c3cd5e6612b9 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -700,7 +700,12 @@ fn do_normalize_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, predicates: Vec>) -> Result>, ErrorReported> { - debug!("do_normalize_predicates({:?})", predicates); + debug!( + "do_normalize_predicates(predicates={:?}, region_context={:?}, cause={:?})", + predicates, + region_context, + cause, + ); let span = cause.span; tcx.infer_ctxt().enter(|infcx| { // FIXME. We should really... do something with these region diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 6ef09d96fd153..f3c570e84009b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1608,10 +1608,21 @@ fn predicates_defined_on<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, ) -> Lrc> { + debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); + debug!( + "predicates_defined_on: explicit_predicates_of({:?}) = {:?}", + def_id, + result, + ); let inferred_outlives = tcx.inferred_outlives_of(def_id); if !inferred_outlives.is_empty() { let span = tcx.def_span(def_id); + debug!( + "predicates_defined_on: inferred_outlives_of({:?}) = {:?}", + def_id, + inferred_outlives, + ); Lrc::make_mut(&mut result) .predicates .extend(inferred_outlives.iter().map(|&p| (p, span))); diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 132da8f5cea8d..101edac04c7d4 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -245,6 +245,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( } } +#[derive(Debug)] pub struct IgnoreSelfTy(bool); /// We also have to check the explicit predicates @@ -270,10 +271,18 @@ pub fn check_explicit_predicates<'tcx>( explicit_map: &mut ExplicitPredicatesMap<'tcx>, ignore_self_ty: IgnoreSelfTy, ) { - debug!("def_id = {:?}", &def_id); - debug!("substs = {:?}", &substs); - debug!("explicit_map = {:?}", explicit_map); - debug!("required_predicates = {:?}", required_predicates); + debug!( + "check_explicit_predicates(def_id={:?}, \ + substs={:?}, \ + explicit_map={:?}, \ + required_predicates={:?}, \ + ignore_self_ty={:?})", + def_id, + substs, + explicit_map, + required_predicates, + ignore_self_ty, + ); let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id); for outlives_predicate in explicit_predicates.iter() { diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index cca77b20d9b30..1eb53ffc730f6 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -67,6 +67,9 @@ fn inferred_outlives_of<'a, 'tcx>( } err.emit(); } + + debug!("inferred_outlives_of({:?}) = {:?}", item_def_id, predicates); + predicates } From 6575988d8e383fedd3d5579577c05ef23e77913b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 16 Nov 2018 08:58:55 -0500 Subject: [PATCH 2/2] handle trait objects formed from traits with `Self::Foo: 'a` clauses --- .../outlives/implicit_infer.rs | 21 ++++++++++++++----- .../ui/rfc-2093-infer-outlives/issue-54467.rs | 17 +++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/rfc-2093-infer-outlives/issue-54467.rs 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() { }