Skip to content

Commit 69a3c55

Browse files
super-tupledaboross
authored andcommitted
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 <daboross@daboross.net>
1 parent 5ea95e7 commit 69a3c55

File tree

5 files changed

+13
-18
lines changed

5 files changed

+13
-18
lines changed

chalk-solve/src/infer/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,10 @@ fn lifetime_constraint_indirect() {
413413
assert_eq!(goals.len(), 2);
414414
assert_eq!(
415415
format!("{:?}", goals[0]),
416-
"InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }",
416+
"InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }",
417417
);
418418
assert_eq!(
419419
format!("{:?}", goals[1]),
420-
"InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }",
420+
"InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }",
421421
);
422422
}

chalk-solve/src/infer/unify.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,8 @@ impl<'t, I: Interner> Unifier<'t, I> {
275275
if mutability_a != mutability_b {
276276
return Err(NoSolution);
277277
}
278-
// The lifetime is `Contravariant`
279-
Zip::zip_with(
280-
self,
281-
variance.xform(Variance::Contravariant),
282-
lifetime_a,
283-
lifetime_b,
284-
)?;
278+
// Zipping lifetimes implies a is a subtype of b, meaning a outlives b
279+
Zip::zip_with(self, variance, lifetime_a, lifetime_b)?;
285280
// The type is `Covariant` when not mut, `Invariant` otherwise
286281
let output_variance = match mutability_a {
287282
Mutability::Not => Variance::Covariant,
@@ -1057,16 +1052,16 @@ impl<'t, I: Interner> Unifier<'t, I> {
10571052
self.goals.push(InEnvironment::new(
10581053
self.environment,
10591054
WhereClause::LifetimeOutlives(LifetimeOutlives {
1060-
a: a.clone(),
1061-
b: b.clone(),
1055+
a: b.clone(),
1056+
b: a.clone(),
10621057
})
10631058
.cast(self.interner),
10641059
));
10651060
}
10661061
if matches!(variance, Variance::Invariant | Variance::Covariant) {
10671062
self.goals.push(InEnvironment::new(
10681063
self.environment,
1069-
WhereClause::LifetimeOutlives(LifetimeOutlives { a: b, b: a }).cast(self.interner),
1064+
WhereClause::LifetimeOutlives(LifetimeOutlives { a, b }).cast(self.interner),
10701065
));
10711066
}
10721067
}

tests/test/misc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ fn basic_region_constraint_from_positive_impl() {
259259
forall<'a, 'b, T> { Ref<'a, 'b, T>: Foo }
260260
} yields_all[SolverChoice::slg(3, None)] {
261261
"substitution [], lifetime constraints [\
262-
InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \
263-
InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \
262+
InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, \
263+
InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 } \
264264
]"
265265
}
266266
}

tests/test/projection.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,10 @@ fn normalize_under_binder_multi() {
799799
} yields_all {
800800
"substitution [?0 := I32], lifetime constraints []",
801801
"for<?U0,?U0> { substitution [?0 := (Deref::Item)<Ref<'^0.0, I32>, '^0.1>], lifetime constraints [\
802-
InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \
803802
InEnvironment { environment: Env([]), goal: '^0.1: '!1_0 }, \
804-
InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
805-
InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }"
803+
InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \
804+
InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \
805+
InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }] }"
806806
}
807807

808808
goal {

tests/test/subtype.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn struct_lifetime_variance() {
4545
}
4646
} yields {
4747
"Unique; substitution [], lifetime constraints [\
48-
InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \
48+
InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 } \
4949
]"
5050
}
5151
}

0 commit comments

Comments
 (0)