Skip to content

Commit 6929013

Browse files
committed
fix subtle bug in NLL type checker
The bug was revealed by the behavior of the old-lub-glb-hr-noteq1.rs test. The old-lub-glb-hr-noteq2 test shows the current 'order dependent' behavior of coercions around higher-ranked functions, at least when running with `-Zborrowck=mir`. Also, run compare-mode=nll.
1 parent c88a76e commit 6929013

30 files changed

+472
-61
lines changed

src/librustc_infer/infer/nll_relate/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,13 @@ where
522522
}
523523

524524
if a == b {
525-
return Ok(a);
525+
// Subtle: if a or b has a bound variable that we are lazilly
526+
// substituting, then even if a == b, it could be that the values we
527+
// will substitute for those bound variables are *not* the same, and
528+
// hence returning `Ok(a)` is incorrect.
529+
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
530+
return Ok(a);
531+
}
526532
}
527533

528534
match (&a.kind, &b.kind) {

src/librustc_mir/borrow_check/type_check/relate_tys.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(super) fn relate_types<'tcx>(
2525
category: ConstraintCategory,
2626
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
2727
) -> Fallible<()> {
28-
debug!("eq_types(a={:?}, b={:?}, locations={:?})", a, b, locations);
28+
debug!("relate_types(a={:?}, v={:?}, b={:?}, locations={:?})", a, v, b, locations);
2929
TypeRelating::new(
3030
infcx,
3131
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),

src/librustc_typeck/check/coercion.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895895
{
896896
let prev_ty = self.resolve_vars_with_obligations(prev_ty);
897897
let new_ty = self.resolve_vars_with_obligations(new_ty);
898-
debug!("coercion::try_find_coercion_lub({:?}, {:?})", prev_ty, new_ty);
898+
debug!(
899+
"coercion::try_find_coercion_lub({:?}, {:?}, exprs={:?} exprs)",
900+
prev_ty,
901+
new_ty,
902+
exprs.len()
903+
);
899904

900905
// Special-case that coercion alone cannot handle:
901906
// Function items or non-capturing closures of differing IDs or InternalSubsts.
@@ -1001,6 +1006,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10011006
Ok(ok) => {
10021007
let (adjustments, target) = self.register_infer_ok_obligations(ok);
10031008
self.apply_adjustments(new, adjustments);
1009+
debug!(
1010+
"coercion::try_find_coercion_lub: was able to coerce from previous type {:?} to new type {:?}",
1011+
prev_ty, new_ty,
1012+
);
10041013
return Ok(target);
10051014
}
10061015
Err(e) => first_error = Some(e),
@@ -1031,6 +1040,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10311040
};
10321041

10331042
if !noop {
1043+
debug!(
1044+
"coercion::try_find_coercion_lub: older expression {:?} had adjustments, requiring LUB",
1045+
expr,
1046+
);
1047+
10341048
return self
10351049
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
10361050
.map(|ok| self.register_infer_ok_obligations(ok));
@@ -1048,6 +1062,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10481062
}
10491063
}
10501064
Ok(ok) => {
1065+
debug!(
1066+
"coercion::try_find_coercion_lub: was able to coerce previous type {:?} to new type {:?}",
1067+
prev_ty, new_ty,
1068+
);
10511069
let (adjustments, target) = self.register_infer_ok_obligations(ok);
10521070
for expr in exprs {
10531071
let expr = expr.as_coercion_site();
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
2+
--> $DIR/associated-types-eq-hr.rs:87:5
3+
|
4+
LL | fn foo<T>()
5+
| --- required by a bound in this
6+
LL | where
7+
LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
8+
| ------------- required by this bound in `foo`
9+
...
10+
LL | foo::<UintStruct>();
11+
| ^^^^^^^^^^^^^^^^^ expected `isize`, found `usize`
12+
|
13+
= note: expected reference `&isize`
14+
found reference `&usize`
15+
16+
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
17+
--> $DIR/associated-types-eq-hr.rs:91:5
18+
|
19+
LL | fn bar<T>()
20+
| --- required by a bound in this
21+
LL | where
22+
LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>,
23+
| ------------- required by this bound in `bar`
24+
...
25+
LL | bar::<IntStruct>();
26+
| ^^^^^^^^^^^^^^^^ expected `usize`, found `isize`
27+
|
28+
= note: expected reference `&usize`
29+
found reference `&isize`
30+
31+
error: aborting due to 2 previous errors
32+
33+
For more information about this error, try `rustc --explain E0271`.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/higher-ranked-projection.rs:25:5
3+
|
4+
LL | foo(());
5+
| ^^^^^^^
6+
7+
error: aborting due to previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/resume-arg-late-bound.rs:15:5
3+
|
4+
LL | test(gen);
5+
| ^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/hr-subtype.rs:45:13
3+
|
4+
LL | gimme::<$t1>(None::<$t2>);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
...
7+
LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
8+
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
9+
| |_____________________________________________- in this macro invocation
10+
|
11+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
12+
13+
error: aborting due to previous error
14+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/hr-subtype.rs:45:13
3+
|
4+
LL | gimme::<$t1>(None::<$t2>);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
...
7+
LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
8+
LL | | fn(&'x u32)) }
9+
| |______________- in this macro invocation
10+
|
11+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
12+
13+
error: aborting due to previous error
14+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/hr-subtype.rs:45:13
3+
|
4+
LL | gimme::<$t1>(None::<$t2>);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
...
7+
LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
8+
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
9+
| |__________________________________- in this macro invocation
10+
|
11+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
12+
13+
error: higher-ranked subtype error
14+
--> $DIR/hr-subtype.rs:45:13
15+
|
16+
LL | gimme::<$t1>(None::<$t2>);
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
18+
...
19+
LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
20+
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
21+
| |__________________________________- in this macro invocation
22+
|
23+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
24+
25+
error: aborting due to 2 previous errors
26+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: higher-ranked subtype error
2+
--> $DIR/hrtb-conflate-regions.rs:27:10
3+
|
4+
LL | fn b() { want_foo2::<SomeStruct>(); }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: higher-ranked subtype error
8+
--> $DIR/hrtb-conflate-regions.rs:27:10
9+
|
10+
LL | fn b() { want_foo2::<SomeStruct>(); }
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)