From e674cf0200347c5e58f8a3867657187b12e7b496 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 14 Aug 2020 21:51:28 +0100 Subject: [PATCH] Normalize super trait bounds when confirming object candidates --- .../src/traits/select/confirmation.rs | 29 +++++++++++++------ .../associated-types/object-normalization.rs | 26 +++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/associated-types/object-normalization.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 21293615bc9..8c58d4191c5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -440,15 +440,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let upcast_trait_ref = upcast_trait_ref.unwrap(); // Check supertraits hold - nested.extend( - tcx.super_predicates_of(trait_predicate.def_id()) - .instantiate(tcx, trait_predicate.trait_ref.substs) - .predicates - .into_iter() - .map(|super_trait| { - Obligation::new(obligation.cause.clone(), obligation.param_env, super_trait) - }), - ); + for super_trait in tcx + .super_predicates_of(trait_predicate.def_id()) + .instantiate(tcx, trait_predicate.trait_ref.substs) + .predicates + .into_iter() + { + let normalized_super_trait = normalize_with_depth_to( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + &super_trait, + &mut nested, + ); + nested.push(Obligation::new( + obligation.cause.clone(), + obligation.param_env.clone(), + normalized_super_trait, + )); + } let assoc_types: Vec<_> = tcx .associated_items(trait_predicate.def_id()) diff --git a/src/test/ui/associated-types/object-normalization.rs b/src/test/ui/associated-types/object-normalization.rs new file mode 100644 index 00000000000..1f93248e10e --- /dev/null +++ b/src/test/ui/associated-types/object-normalization.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength + +// Check that we normalize super predicates for object candidates. + +// check-pass + +use std::ops::Index; + +fn next<'a, T>(s: &'a mut dyn SVec) { + // To prove + // `dyn SVec: SVec` + // we need to show + // `dyn SVec as Index>::Output == as SVec>::Item` + // which, with the current normalization strategy, has to be eagerly + // normalized to: + // `dyn SVec as Index>::Output == T`. + let _ = s.len(); +} + +trait SVec: Index::Item> { + type Item; + + fn len(&self) -> usize; +} + +fn main() {}