]> git.lizzy.rs Git - rust.git/commitdiff
Use a dummy outlives requirement for `where Type:,` (see #53696)
authorscalexm <alexandre@scalexm.fr>
Thu, 1 Nov 2018 14:09:02 +0000 (15:09 +0100)
committerscalexm <alexandre@scalexm.fr>
Tue, 13 Nov 2018 11:28:43 +0000 (12:28 +0100)
A `WF(Type)` predicate was used previously, which did not play
well with implied bounds in chalk.

src/librustc_traits/lowering/mod.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/test/ui/chalkify/lower_trait_where_clause.stderr

index 27bf0a757b2553c1ecb5a2159c0c0c4b648dffd1..471c0e7abbca6711a8144ca0531debd6b4d849cf 100644 (file)
@@ -113,13 +113,14 @@ fn lower(&self) -> PolyDomainGoal<'tcx> {
             Predicate::RegionOutlives(predicate) => predicate.lower(),
             Predicate::TypeOutlives(predicate) => predicate.lower(),
             Predicate::Projection(predicate) => predicate.lower(),
-            Predicate::WellFormed(ty) => {
-                ty::Binder::dummy(DomainGoal::WellFormed(WellFormed::Ty(*ty)))
+
+            Predicate::WellFormed(..) |
+            Predicate::ObjectSafe(..) |
+            Predicate::ClosureKind(..) |
+            Predicate::Subtype(..) |
+            Predicate::ConstEvaluatable(..) => {
+                bug!("unexpected predicate {}", self)
             }
-            Predicate::ObjectSafe(..)
-            | Predicate::ClosureKind(..)
-            | Predicate::Subtype(..)
-            | Predicate::ConstEvaluatable(..) => unimplemented!(),
         }
     }
 }
index 70af837076f1acce56eadb31ae47b1d71c076d6d..d2dc226aca2501fd9e14da18b08cd795770e1365 100644 (file)
@@ -1857,8 +1857,9 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
             &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
                 let ty = icx.to_ty(&bound_pred.bounded_ty);
 
-                // Keep the type around in a WF predicate, in case of no bounds.
-                // That way, `where Ty:` is not a complete noop (see #53696).
+                // Keep the type around in a dummy predicate, in case of no bounds.
+                // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
+                // is still checked for WF.
                 if bound_pred.bounds.is_empty() {
                     if let ty::Param(_) = ty.sty {
                         // This is a `where T:`, which can be in the HIR from the
@@ -1869,7 +1870,10 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
                         // compiler/tooling bugs from not handling WF predicates.
                     } else {
                         let span = bound_pred.bounded_ty.span;
-                        predicates.push((ty::Predicate::WellFormed(ty), span));
+                        let predicate = ty::OutlivesPredicate(ty, tcx.mk_region(ty::ReEmpty));
+                        predicates.push(
+                            (ty::Predicate::TypeOutlives(ty::Binder::dummy(predicate)), span)
+                        );
                     }
                 }
 
index f514cb83a1fed636489797a9291ddf5962022a13..77782c19b725238b881eedc0290a3bbf878b934b 100644 (file)
@@ -1325,15 +1325,10 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
             Predicate::RegionOutlives(ref pred) => pred.clean(cx),
             Predicate::TypeOutlives(ref pred) => pred.clean(cx),
             Predicate::Projection(ref pred) => pred.clean(cx),
-            Predicate::WellFormed(ty) => {
-                // This comes from `where Ty:` (i.e. no bounds) (see #53696).
-                WherePredicate::BoundPredicate {
-                    ty: ty.clean(cx),
-                    bounds: vec![],
-                }
-            }
-            Predicate::ObjectSafe(_) => panic!("not user writable"),
-            Predicate::ClosureKind(..) => panic!("not user writable"),
+
+            Predicate::WellFormed(..) |
+            Predicate::ObjectSafe(..) |
+            Predicate::ClosureKind(..) |
             Predicate::ConstEvaluatable(..) => panic!("not user writable"),
         }
     }
index f04f53f24969a45dff6e4b439c1132052cb82c8a..fcd516c89ba3326ede1278e5a9ee42259bd6c7d9 100644 (file)
@@ -8,8 +8,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    = note: forall<'a, 'b, Self, T, U> { Implemented(Self: Foo<'a, 'b, T, U>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
    = note: forall<'a, 'b, Self, T, U> { RegionOutlives('a: 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
    = note: forall<'a, 'b, Self, T, U> { TypeOutlives(U: 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
-   = note: forall<'a, 'b, Self, T, U> { WellFormed(Self: Foo<'a, 'b, T, U>) :- Implemented(Self: Foo<'a, 'b, T, U>), WellFormed(T: std::borrow::Borrow<U>), TypeOutlives(U: 'b), RegionOutlives('a: 'b), WellFormed(std::boxed::Box<T>). }
-   = note: forall<'a, 'b, Self, T, U> { WellFormed(std::boxed::Box<T>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
+   = note: forall<'a, 'b, Self, T, U> { TypeOutlives(std::boxed::Box<T>: '<empty>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
+   = note: forall<'a, 'b, Self, T, U> { WellFormed(Self: Foo<'a, 'b, T, U>) :- Implemented(Self: Foo<'a, 'b, T, U>), WellFormed(T: std::borrow::Borrow<U>), TypeOutlives(U: 'b), RegionOutlives('a: 'b), TypeOutlives(std::boxed::Box<T>: '<empty>). }
 
 error: aborting due to previous error