about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFabian Zaiser <fabian.zaiser@gmail.com>2018-04-11 21:20:25 +0200
committerFabian Zaiser <fabian.zaiser@gmail.com>2018-04-15 23:32:58 +0200
commitde475582c4dc1c8f532eed578d574979283f1c42 (patch)
tree754a4d06a941680454643a0d8cdca99eedb209cf
parentecd41976fc5a13e8c9a706496d714f655a5ab995 (diff)
downloadrust-de475582c4dc1c8f532eed578d574979283f1c42.tar.gz
rust-de475582c4dc1c8f532eed578d574979283f1c42.zip
Stop duplicating where clauses from impl's.
-rw-r--r--src/librustc_traits/lowering.rs16
-rw-r--r--src/test/ui/chalkify/lower_impl.stderr2
2 files changed, 8 insertions, 10 deletions
diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs
index 1b73cd48099..9da2c49ee5d 100644
--- a/src/librustc_traits/lowering.rs
+++ b/src/librustc_traits/lowering.rs
@@ -251,16 +251,15 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
     // Rule Normalize-From-Impl (see rustc guide)
     //
     // ```impl<P0..Pn> Trait<A1..An> for A0
-    // where WC
     // {
-    //     type AssocType<Pn+1..Pm> where WC1 = T;
+    //     type AssocType<Pn+1..Pm> where WC = T;
     // }```
     //
     // ```
     // forall<P0..Pm> {
     //   forall<Pn+1..Pm> {
     //     Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
-    //       WC && WC1
+    //       Implemented(A0: Trait<A1..An>) && WC
     //   }
     // }
     // ```
@@ -276,19 +275,18 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
     let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
     // `T`
     let ty = tcx.type_of(item_id);
+    // `Implemented(A0: Trait<A1..An>)`
+    let trait_implemented = ty::Binder::dummy(ty::TraitPredicate { trait_ref }.lower());
     // `WC`
-    let impl_where_clauses = tcx.predicates_of(impl_id).predicates.lower();
-    // `WC1`
     let item_where_clauses = tcx.predicates_of(item_id).predicates.lower();
-    // `WC && WC1`
-    let mut where_clauses = vec![];
-    where_clauses.extend(impl_where_clauses);
+    // `Implemented(A0: Trait<A1..An>) && WC`
+    let mut where_clauses = vec![trait_implemented];
     where_clauses.extend(item_where_clauses);
     // `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
     let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name);
     // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T)`
     let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty });
-    // `Normalize(... -> T) :- WC && WC1`
+    // `Normalize(... -> T) :- ...`
     let clause = ProgramClause {
         goal: normalize_goal,
         hypotheses: where_clauses.into_iter().map(|wc| wc.into()).collect(),
diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr
index 5a32b8567b9..f253f9847d1 100644
--- a/src/test/ui/chalkify/lower_impl.stderr
+++ b/src/test/ui/chalkify/lower_impl.stderr
@@ -4,7 +4,7 @@ error: Implemented(T: Foo) :- ProjectionEq(<T as std::iter::Iterator>::Item == i
 LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :-
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: Normalize(<T as Bar>::Assoc == std::vec::Vec<T>) :- ProjectionEq(<T as std::iter::Iterator>::Item == i32), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized).
+error: Normalize(<T as Bar>::Assoc == std::vec::Vec<T>) :- Implemented(T: Bar).
   --> $DIR/lower_impl.rs:23:5
    |
 LL |     #[rustc_dump_program_clauses] //~ ERROR Normalize(<T as Bar>::Assoc == std::vec::Vec<T>) :-