Skip to content

Commit

Permalink
Fix a bug in implied bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
scalexm committed Mar 20, 2019
1 parent 4effdd2 commit d6a2b7c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 7 deletions.
9 changes: 5 additions & 4 deletions src/librustc_traits/lowering/mod.rs
Expand Up @@ -337,7 +337,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
//
// ```
// forall<P1..Pn> {
// WellFormed(Ty<...>) :- WC1, ..., WCm`
// WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
// }
// ```

Expand All @@ -354,13 +354,14 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
.map(|(wc, _)| wc.lower())
.collect::<Vec<_>>();

// `WellFormed(Ty<...>) :- WC1, ..., WCm`
// `WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
let well_formed_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
hypotheses: tcx.mk_goals(
where_clauses
.iter()
.map(|wc| wc.subst(tcx, bound_vars))
.map(|wc| wc.map_bound(|bound| bound.into_well_formed_goal()))
.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
),
category: ProgramClauseCategory::WellFormed,
Expand Down Expand Up @@ -457,13 +458,13 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
// ```
// forall<Self, P1..Pn, Pn+1..Pm> {
// WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
// :- Implemented(Self: Trait<P1..Pn>)
// :- WellFormed(Self: Trait<P1..Pn>)
// }
// ```

let trait_predicate = ty::TraitPredicate { trait_ref };
let hypothesis = tcx.mk_goal(
DomainGoal::Holds(WhereClause::Implemented(trait_predicate)).into_goal()
DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)).into_goal()
);

let wf_clause = ProgramClause {
Expand Down
28 changes: 28 additions & 0 deletions src/test/compile-fail/chalkify/recursive_where_clause_on_type.rs
@@ -0,0 +1,28 @@
// compile-flags: -Z chalk

#![feature(trivial_bounds)]

trait Bar {
fn foo();
}
trait Foo: Bar { }

struct S where S: Foo;

impl Foo for S {
}

fn bar<T: Bar>() {
T::foo();
}

fn foo<T: Foo>() {
bar::<T>()
}

fn main() {
// For some reason, the error is duplicated...

foo::<S>() //~ ERROR the type `S` is not well-formed (chalk)
//~^ ERROR the type `S` is not well-formed (chalk)
}
2 changes: 1 addition & 1 deletion src/test/ui/chalkify/lower_env2.stderr
Expand Up @@ -6,7 +6,7 @@ LL | #[rustc_dump_program_clauses]
|
= note: forall<'a, T> { FromEnv(T: Foo) :- FromEnv(S<'a, T>). }
= note: forall<'a, T> { TypeOutlives(T: 'a) :- FromEnv(S<'a, T>). }
= note: forall<'a, T> { WellFormed(S<'a, T>) :- Implemented(T: Foo), TypeOutlives(T: 'a). }
= note: forall<'a, T> { WellFormed(S<'a, T>) :- WellFormed(T: Foo), TypeOutlives(T: 'a). }

error: program clause dump
--> $DIR/lower_env2.rs:11:1
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/chalkify/lower_struct.stderr
Expand Up @@ -7,7 +7,7 @@ LL | #[rustc_dump_program_clauses]
= note: forall<'a, T> { FromEnv(T: std::marker::Sized) :- FromEnv(Foo<'a, T>). }
= note: forall<'a, T> { FromEnv(std::boxed::Box<T>: std::clone::Clone) :- FromEnv(Foo<'a, T>). }
= note: forall<'a, T> { TypeOutlives(T: 'a) :- FromEnv(Foo<'a, T>). }
= note: forall<'a, T> { WellFormed(Foo<'a, T>) :- Implemented(T: std::marker::Sized), Implemented(std::boxed::Box<T>: std::clone::Clone), TypeOutlives(T: 'a). }
= note: forall<'a, T> { WellFormed(Foo<'a, T>) :- WellFormed(T: std::marker::Sized), WellFormed(std::boxed::Box<T>: std::clone::Clone), TypeOutlives(T: 'a). }

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/chalkify/lower_trait.stderr
Expand Up @@ -18,7 +18,7 @@ LL | #[rustc_dump_program_clauses]
= note: forall<Self, S, T, ^3> { ProjectionEq(<Self as Foo<S, T>>::Assoc == ^3) :- Normalize(<Self as Foo<S, T>>::Assoc -> ^3). }
= note: forall<Self, S, T> { FromEnv(Self: Foo<S, T>) :- FromEnv(Unnormalized(<Self as Foo<S, T>>::Assoc)). }
= note: forall<Self, S, T> { ProjectionEq(<Self as Foo<S, T>>::Assoc == Unnormalized(<Self as Foo<S, T>>::Assoc)). }
= note: forall<Self, S, T> { WellFormed(Unnormalized(<Self as Foo<S, T>>::Assoc)) :- Implemented(Self: Foo<S, T>). }
= note: forall<Self, S, T> { WellFormed(Unnormalized(<Self as Foo<S, T>>::Assoc)) :- WellFormed(Self: Foo<S, T>). }

error: aborting due to 2 previous errors

0 comments on commit d6a2b7c

Please sign in to comment.