Skip to content

Commit b224397

Browse files
committed
issue better error message when LUB/GLB diverge under new behavior
1 parent 397973b commit b224397

File tree

8 files changed

+138
-1
lines changed

8 files changed

+138
-1
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,16 +762,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
762762
}
763763
}
764764

765-
self.note_error_origin(diag, &cause);
766765
self.check_and_note_conflicting_crates(diag, terr, span);
767766
self.tcx.note_and_explain_type_err(diag, terr, span);
767+
768+
// It reads better to have the error origin as the final
769+
// thing.
770+
self.note_error_origin(diag, &cause);
768771
}
769772

770773
pub fn report_and_explain_type_error(&self,
771774
trace: TypeTrace<'tcx>,
772775
terr: &TypeError<'tcx>)
773776
-> DiagnosticBuilder<'tcx>
774777
{
778+
debug!("report_and_explain_type_error(trace={:?}, terr={:?})",
779+
trace,
780+
terr);
781+
775782
let span = trace.cause.span;
776783
let failure_str = trace.cause.as_failure_str();
777784
let mut diag = match trace.cause.code {

src/librustc/infer/glb.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7575
-> RelateResult<'tcx, ty::Binder<T>>
7676
where T: Relate<'tcx>
7777
{
78+
debug!("binders(a={:?}, b={:?})", a, b);
7879
let was_error = self.infcx().probe(|_snapshot| {
7980
// Subtle: use a fresh combine-fields here because we recover
8081
// from Err. Doing otherwise could propagate obligations out
@@ -84,13 +85,15 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
8485
.higher_ranked_glb(a, b, self.a_is_expected)
8586
.is_err()
8687
});
88+
debug!("binders: was_error={:?}", was_error);
8789

8890
// When higher-ranked types are involved, computing the LUB is
8991
// very challenging, switch to invariance. This is obviously
9092
// overly conservative but works ok in practice.
9193
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
9294
Ok(_) => Ok(a.clone()),
9395
Err(err) => {
96+
debug!("binders: error occurred, was_error={:?}", was_error);
9497
if !was_error {
9598
Err(TypeError::OldStyleLUB(Box::new(err)))
9699
} else {

src/librustc/infer/lub.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7575
-> RelateResult<'tcx, ty::Binder<T>>
7676
where T: Relate<'tcx>
7777
{
78+
debug!("binders(a={:?}, b={:?})", a, b);
7879
let was_error = self.infcx().probe(|_snapshot| {
7980
// Subtle: use a fresh combine-fields here because we recover
8081
// from Err. Doing otherwise could propagate obligations out
@@ -84,13 +85,15 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
8485
.higher_ranked_lub(a, b, self.a_is_expected)
8586
.is_err()
8687
});
88+
debug!("binders: was_error={:?}", was_error);
8789

8890
// When higher-ranked types are involved, computing the LUB is
8991
// very challenging, switch to invariance. This is obviously
9092
// overly conservative but works ok in practice.
9193
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
9294
Ok(_) => Ok(a.clone()),
9395
Err(err) => {
96+
debug!("binders: error occurred, was_error={:?}", was_error);
9497
if !was_error {
9598
Err(TypeError::OldStyleLUB(Box::new(err)))
9699
} else {

src/librustc/ty/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
298298
db.span_note(found.origin_span,
299299
"...that also applies to the same type variable here");
300300
}
301+
OldStyleLUB(err) => {
302+
db.note("this was previously accepted by the compiler but has been phased out");
303+
db.note("for more information, see https://github.com/rust-lang/rust/issues/45852");
304+
305+
self.note_and_explain_type_err(db, &err, sp);
306+
}
301307
_ => {}
302308
}
303309
}

src/test/ui/lub-glb/old-lub-glb-hr.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we give a note when the old LUB/GLB algorithm would have
12+
// succeeded but the new code (which is stricter) gives an error.
13+
14+
fn foo(
15+
x: fn(&u8, &u8),
16+
y: for<'a> fn(&'a u8, &'a u8),
17+
) {
18+
let z = match 22 {
19+
0 => x,
20+
_ => y,
21+
};
22+
}
23+
24+
fn bar(
25+
x: fn(&u8, &u8),
26+
y: for<'a> fn(&'a u8, &'a u8),
27+
) {
28+
let z = match 22 {
29+
// No error with an explicit cast:
30+
0 => x as for<'a> fn(&'a u8, &'a u8),
31+
_ => y,
32+
};
33+
}
34+
35+
fn main() {
36+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0308]: match arms have incompatible types
2+
--> $DIR/old-lub-glb-hr.rs:18:13
3+
|
4+
18 | let z = match 22 {
5+
| _____________^
6+
19 | | 0 => x,
7+
20 | | _ => y,
8+
21 | | };
9+
| |_____^ expected bound lifetime parameter, found concrete lifetime
10+
|
11+
= note: expected type `for<'r, 's> fn(&'r u8, &'s u8)`
12+
found type `for<'a> fn(&'a u8, &'a u8)`
13+
= note: this was previously accepted by the compiler but has been phased out
14+
= note: for more information, see https://github.com/rust-lang/rust/issues/45852
15+
note: match arm with an incompatible type
16+
--> $DIR/old-lub-glb-hr.rs:20:14
17+
|
18+
20 | _ => y,
19+
| ^
20+
21+
error: aborting due to previous error
22+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we give a note when the old LUB/GLB algorithm would have
12+
// succeeded but the new code (which is stricter) gives an error.
13+
14+
trait Foo<T, U> { }
15+
16+
fn foo(
17+
x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
18+
y: &for<'a> Foo<&'a u8, &'a u8>,
19+
) {
20+
let z = match 22 {
21+
0 => x,
22+
_ => y,
23+
};
24+
}
25+
26+
fn bar(
27+
x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
28+
y: &for<'a> Foo<&'a u8, &'a u8>,
29+
) {
30+
// Accepted with explicit case:
31+
let z = match 22 {
32+
0 => x as &for<'a> Foo<&'a u8, &'a u8>,
33+
_ => y,
34+
};
35+
}
36+
37+
fn main() {
38+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0308]: match arms have incompatible types
2+
--> $DIR/old-lub-glb-object.rs:20:13
3+
|
4+
20 | let z = match 22 {
5+
| _____________^
6+
21 | | 0 => x,
7+
22 | | _ => y,
8+
23 | | };
9+
| |_____^ expected bound lifetime parameter 'a, found concrete lifetime
10+
|
11+
= note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>`
12+
found type `&for<'a> Foo<&'a u8, &'a u8>`
13+
= note: this was previously accepted by the compiler but has been phased out
14+
= note: for more information, see https://github.com/rust-lang/rust/issues/45852
15+
note: match arm with an incompatible type
16+
--> $DIR/old-lub-glb-object.rs:22:14
17+
|
18+
22 | _ => y,
19+
| ^
20+
21+
error: aborting due to previous error
22+

0 commit comments

Comments
 (0)