issue better error message when LUB/GLB diverge under new behavior
This commit is contained in:
parent
397973b601
commit
b224397b7c
@ -762,9 +762,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
self.note_error_origin(diag, &cause);
|
||||
self.check_and_note_conflicting_crates(diag, terr, span);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, span);
|
||||
|
||||
// It reads better to have the error origin as the final
|
||||
// thing.
|
||||
self.note_error_origin(diag, &cause);
|
||||
}
|
||||
|
||||
pub fn report_and_explain_type_error(&self,
|
||||
@ -772,6 +775,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
terr: &TypeError<'tcx>)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
debug!("report_and_explain_type_error(trace={:?}, terr={:?})",
|
||||
trace,
|
||||
terr);
|
||||
|
||||
let span = trace.cause.span;
|
||||
let failure_str = trace.cause.as_failure_str();
|
||||
let mut diag = match trace.cause.code {
|
||||
|
@ -75,6 +75,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
-> RelateResult<'tcx, ty::Binder<T>>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("binders(a={:?}, b={:?})", a, b);
|
||||
let was_error = self.infcx().probe(|_snapshot| {
|
||||
// Subtle: use a fresh combine-fields here because we recover
|
||||
// from Err. Doing otherwise could propagate obligations out
|
||||
@ -84,6 +85,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
.higher_ranked_glb(a, b, self.a_is_expected)
|
||||
.is_err()
|
||||
});
|
||||
debug!("binders: was_error={:?}", was_error);
|
||||
|
||||
// When higher-ranked types are involved, computing the LUB is
|
||||
// very challenging, switch to invariance. This is obviously
|
||||
@ -91,6 +93,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
|
||||
Ok(_) => Ok(a.clone()),
|
||||
Err(err) => {
|
||||
debug!("binders: error occurred, was_error={:?}", was_error);
|
||||
if !was_error {
|
||||
Err(TypeError::OldStyleLUB(Box::new(err)))
|
||||
} else {
|
||||
|
@ -75,6 +75,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
-> RelateResult<'tcx, ty::Binder<T>>
|
||||
where T: Relate<'tcx>
|
||||
{
|
||||
debug!("binders(a={:?}, b={:?})", a, b);
|
||||
let was_error = self.infcx().probe(|_snapshot| {
|
||||
// Subtle: use a fresh combine-fields here because we recover
|
||||
// from Err. Doing otherwise could propagate obligations out
|
||||
@ -84,6 +85,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
.higher_ranked_lub(a, b, self.a_is_expected)
|
||||
.is_err()
|
||||
});
|
||||
debug!("binders: was_error={:?}", was_error);
|
||||
|
||||
// When higher-ranked types are involved, computing the LUB is
|
||||
// very challenging, switch to invariance. This is obviously
|
||||
@ -91,6 +93,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
|
||||
Ok(_) => Ok(a.clone()),
|
||||
Err(err) => {
|
||||
debug!("binders: error occurred, was_error={:?}", was_error);
|
||||
if !was_error {
|
||||
Err(TypeError::OldStyleLUB(Box::new(err)))
|
||||
} else {
|
||||
|
@ -298,6 +298,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
db.span_note(found.origin_span,
|
||||
"...that also applies to the same type variable here");
|
||||
}
|
||||
OldStyleLUB(err) => {
|
||||
db.note("this was previously accepted by the compiler but has been phased out");
|
||||
db.note("for more information, see https://github.com/rust-lang/rust/issues/45852");
|
||||
|
||||
self.note_and_explain_type_err(db, &err, sp);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
36
src/test/ui/lub-glb/old-lub-glb-hr.rs
Normal file
36
src/test/ui/lub-glb/old-lub-glb-hr.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we give a note when the old LUB/GLB algorithm would have
|
||||
// succeeded but the new code (which is stricter) gives an error.
|
||||
|
||||
fn foo(
|
||||
x: fn(&u8, &u8),
|
||||
y: for<'a> fn(&'a u8, &'a u8),
|
||||
) {
|
||||
let z = match 22 {
|
||||
0 => x,
|
||||
_ => y,
|
||||
};
|
||||
}
|
||||
|
||||
fn bar(
|
||||
x: fn(&u8, &u8),
|
||||
y: for<'a> fn(&'a u8, &'a u8),
|
||||
) {
|
||||
let z = match 22 {
|
||||
// No error with an explicit cast:
|
||||
0 => x as for<'a> fn(&'a u8, &'a u8),
|
||||
_ => y,
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
22
src/test/ui/lub-glb/old-lub-glb-hr.stderr
Normal file
22
src/test/ui/lub-glb/old-lub-glb-hr.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0308]: match arms have incompatible types
|
||||
--> $DIR/old-lub-glb-hr.rs:18:13
|
||||
|
|
||||
18 | let z = match 22 {
|
||||
| _____________^
|
||||
19 | | 0 => x,
|
||||
20 | | _ => y,
|
||||
21 | | };
|
||||
| |_____^ expected bound lifetime parameter, found concrete lifetime
|
||||
|
|
||||
= note: expected type `for<'r, 's> fn(&'r u8, &'s u8)`
|
||||
found type `for<'a> fn(&'a u8, &'a u8)`
|
||||
= note: this was previously accepted by the compiler but has been phased out
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/45852
|
||||
note: match arm with an incompatible type
|
||||
--> $DIR/old-lub-glb-hr.rs:20:14
|
||||
|
|
||||
20 | _ => y,
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
38
src/test/ui/lub-glb/old-lub-glb-object.rs
Normal file
38
src/test/ui/lub-glb/old-lub-glb-object.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we give a note when the old LUB/GLB algorithm would have
|
||||
// succeeded but the new code (which is stricter) gives an error.
|
||||
|
||||
trait Foo<T, U> { }
|
||||
|
||||
fn foo(
|
||||
x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
|
||||
y: &for<'a> Foo<&'a u8, &'a u8>,
|
||||
) {
|
||||
let z = match 22 {
|
||||
0 => x,
|
||||
_ => y,
|
||||
};
|
||||
}
|
||||
|
||||
fn bar(
|
||||
x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
|
||||
y: &for<'a> Foo<&'a u8, &'a u8>,
|
||||
) {
|
||||
// Accepted with explicit case:
|
||||
let z = match 22 {
|
||||
0 => x as &for<'a> Foo<&'a u8, &'a u8>,
|
||||
_ => y,
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
22
src/test/ui/lub-glb/old-lub-glb-object.stderr
Normal file
22
src/test/ui/lub-glb/old-lub-glb-object.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0308]: match arms have incompatible types
|
||||
--> $DIR/old-lub-glb-object.rs:20:13
|
||||
|
|
||||
20 | let z = match 22 {
|
||||
| _____________^
|
||||
21 | | 0 => x,
|
||||
22 | | _ => y,
|
||||
23 | | };
|
||||
| |_____^ expected bound lifetime parameter 'a, found concrete lifetime
|
||||
|
|
||||
= note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>`
|
||||
found type `&for<'a> Foo<&'a u8, &'a u8>`
|
||||
= note: this was previously accepted by the compiler but has been phased out
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/45852
|
||||
note: match arm with an incompatible type
|
||||
--> $DIR/old-lub-glb-object.rs:22:14
|
||||
|
|
||||
22 | _ => y,
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user