From d5b0ffcfec618d57c9a7bfc35adf26f5420cfc35 Mon Sep 17 00:00:00 2001 From: Super Tuple Date: Sat, 31 Oct 2020 22:40:39 -0700 Subject: [PATCH] Fix incosistent usage of push_lifetime_outlives The code that relates Adt's was using `push_lifetime_outlives_goals` in a way that assumed it would push a outlives b when the variance is covariant. The code that relates two references assumed that it would push a constraint b outlives a when the variance was covariant. This latter behavior was what the function actually did, despite its name implying the opposite. This commit changes the behavior of `push_lifetime_outlives_goals` to push a outlives b when the variance is covariant, and updates the code that relates references. We also updated an incorrect test case where a reference was used in a struct. This test case would have failed (because `push_lifetime_outlives_goals` was inverted), but the constraints in the expected output were also incorrectly inverted. The output of two additional test cases also were updated because the constraints were emitted in a different order after making the update. Co-authored-by: David Ross --- chalk-solve/src/infer/test.rs | 4 ++-- chalk-solve/src/infer/unify.rs | 15 +++++---------- tests/test/misc.rs | 4 ++-- tests/test/projection.rs | 6 +++--- tests/test/subtype.rs | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/chalk-solve/src/infer/test.rs b/chalk-solve/src/infer/test.rs index a8671b01119..0fa6878581e 100644 --- a/chalk-solve/src/infer/test.rs +++ b/chalk-solve/src/infer/test.rs @@ -413,10 +413,10 @@ fn lifetime_constraint_indirect() { assert_eq!(goals.len(), 2); assert_eq!( format!("{:?}", goals[0]), - "InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }", + "InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }", ); assert_eq!( format!("{:?}", goals[1]), - "InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }", + "InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }", ); } diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index 7670176ca20..2593c87f1cc 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -275,13 +275,8 @@ impl<'t, I: Interner> Unifier<'t, I> { if mutability_a != mutability_b { return Err(NoSolution); } - // The lifetime is `Contravariant` - Zip::zip_with( - self, - variance.xform(Variance::Contravariant), - lifetime_a, - lifetime_b, - )?; + // Zipping lifetimes implies a is a subtype of b, meaning a outlives b + Zip::zip_with(self, variance, lifetime_a, lifetime_b)?; // The type is `Covariant` when not mut, `Invariant` otherwise let output_variance = match mutability_a { Mutability::Not => Variance::Covariant, @@ -1035,8 +1030,8 @@ impl<'t, I: Interner> Unifier<'t, I> { self.goals.push(InEnvironment::new( self.environment, WhereClause::LifetimeOutlives(LifetimeOutlives { - a: a.clone(), - b: b.clone(), + a: b.clone(), + b: a.clone(), }) .cast(self.interner), )); @@ -1044,7 +1039,7 @@ impl<'t, I: Interner> Unifier<'t, I> { if matches!(variance, Variance::Invariant | Variance::Covariant) { self.goals.push(InEnvironment::new( self.environment, - WhereClause::LifetimeOutlives(LifetimeOutlives { a: b, b: a }).cast(self.interner), + WhereClause::LifetimeOutlives(LifetimeOutlives { a, b }).cast(self.interner), )); } } diff --git a/tests/test/misc.rs b/tests/test/misc.rs index 66d42b5cd9e..a7cbb02593c 100644 --- a/tests/test/misc.rs +++ b/tests/test/misc.rs @@ -259,8 +259,8 @@ fn basic_region_constraint_from_positive_impl() { forall<'a, 'b, T> { Ref<'a, 'b, T>: Foo } } yields_all[SolverChoice::slg(3, None)] { "substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ + InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, \ + InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 } \ ]" } } diff --git a/tests/test/projection.rs b/tests/test/projection.rs index 25172b4a3cf..2898206ea03 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -799,10 +799,10 @@ fn normalize_under_binder_multi() { } yields_all { "substitution [?0 := I32], lifetime constraints []", "for { substitution [?0 := (Deref::Item), '^0.1>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \ InEnvironment { environment: Env([]), goal: '^0.1: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }" + InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \ + InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ + InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }] }" } goal { diff --git a/tests/test/subtype.rs b/tests/test/subtype.rs index c4db22a6237..c622d3d5299 100644 --- a/tests/test/subtype.rs +++ b/tests/test/subtype.rs @@ -45,7 +45,7 @@ fn struct_lifetime_variance() { } } yields { "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ + InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 } \ ]" } }