From 79b6c41bc2d4e9cb9a0c92c0c446882a0cf1a804 Mon Sep 17 00:00:00 2001 From: scalexm Date: Thu, 1 Nov 2018 15:09:02 +0100 Subject: [PATCH] Use a dummy outlives requirement for `where Type:,` (see #53696) A `WF(Type)` predicate was used previously, which did not play well with implied bounds in chalk. --- src/librustc_traits/lowering/mod.rs | 13 +++++++------ src/librustc_typeck/collect.rs | 10 +++++++--- src/librustdoc/clean/mod.rs | 13 ++++--------- .../ui/chalkify/lower_trait_where_clause.stderr | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 27bf0a757b2..471c0e7abbc 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -113,13 +113,14 @@ impl<'tcx> Lower> for ty::Predicate<'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!(), } } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 70af837076f..d2dc226aca2 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1857,8 +1857,9 @@ fn explicit_predicates_of<'a, 'tcx>( &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 explicit_predicates_of<'a, 'tcx>( // 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) + ); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f514cb83a1f..77782c19b72 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1325,15 +1325,10 @@ impl<'a> Clean for ty::Predicate<'a> { 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"), } } diff --git a/src/test/ui/chalkify/lower_trait_where_clause.stderr b/src/test/ui/chalkify/lower_trait_where_clause.stderr index f04f53f2496..fcd516c89ba 100644 --- a/src/test/ui/chalkify/lower_trait_where_clause.stderr +++ b/src/test/ui/chalkify/lower_trait_where_clause.stderr @@ -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), TypeOutlives(U: 'b), RegionOutlives('a: 'b), WellFormed(std::boxed::Box). } - = note: forall<'a, 'b, Self, T, U> { WellFormed(std::boxed::Box) :- FromEnv(Self: Foo<'a, 'b, T, U>). } + = note: forall<'a, 'b, Self, T, U> { TypeOutlives(std::boxed::Box: ') :- 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), TypeOutlives(U: 'b), RegionOutlives('a: 'b), TypeOutlives(std::boxed::Box: '). } error: aborting due to previous error