diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 131e1defc1f..87c58bf8ae7 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -199,19 +199,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { mir_def_id: DefId, fr: RegionVid, outlived_fr: RegionVid, - blame_span: Span, errors_buffer: &mut Vec, ) { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - let tables = infcx.tcx.typeck_tables_of(mir_def_id); - let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables)); - if let Some(_error_reported) = nice.try_report() { - return; - } - } - // Find all paths let constraint_paths = self.find_constraint_paths_between_regions(fr, |r| r == outlived_fr); debug!("report_error: constraint_paths={:#?}", constraint_paths); @@ -233,6 +224,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Get a span let (category, span) = categorized_path.first().unwrap(); + // Check if we can use one of the "nice region errors". + if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { + let tables = infcx.tcx.typeck_tables_of(mir_def_id); + let nice = NiceRegionError::new_from_span(infcx.tcx, *span, o, f, Some(tables)); + if let Some(_error_reported) = nice.try_report() { + return; + } + } + let category = match ( category, self.universal_regions.is_local_free_region(fr), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 3ba95895bfd..ea1e8b346bd 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -921,7 +921,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // to report the error. This gives better error messages // in some cases. self.report_error( - mir, infcx, mir_def_id, longer_fr, shorter_fr, blame_span, errors_buffer); + mir, infcx, mir_def_id, longer_fr, shorter_fr, errors_buffer); } } } diff --git a/src/test/ui/issue-40288-2.nll.stderr b/src/test/ui/issue-40288-2.nll.stderr index fcff5c6a8ed..319e7ef3860 100644 --- a/src/test/ui/issue-40288-2.nll.stderr +++ b/src/test/ui/issue-40288-2.nll.stderr @@ -35,20 +35,22 @@ LL | let mut out = Struct { head: x, _tail: [()] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0621]: explicit lifetime required in the type of `y` - --> $DIR/issue-40288-2.rs:14:9 + --> $DIR/issue-40288-2.rs:16:31 | LL | fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { | - consider changing the type of `y` to `&'a T` -LL | let mut out = [x]; - | ^^^^^^^ lifetime `'a` required +... +LL | let slice: &mut [_] = &mut out; + | ^^^^^^^^ lifetime `'a` required error[E0621]: explicit lifetime required in the type of `y` - --> $DIR/issue-40288-2.rs:29:9 + --> $DIR/issue-40288-2.rs:31:41 | LL | fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { | - consider changing the type of `y` to `&'a T` -LL | let mut out = Struct { head: x, _tail: [()] }; - | ^^^^^^^ lifetime `'a` required +... +LL | let dst: &mut Struct<_, [()]> = &mut out; + | ^^^^^^^^ lifetime `'a` required error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.nll.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.nll.stderr index 1e45914138d..4d9517eca60 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.nll.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.nll.stderr @@ -5,12 +5,12 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime | ^ error[E0621]: explicit lifetime required in parameter type - --> $DIR/ex1-return-one-existing-name-if-else-3.rs:11:13 + --> $DIR/ex1-return-one-existing-name-if-else-3.rs:11:16 | LL | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 { - | -^---- - | || - | |lifetime `'a` required + | ----^- + | | | + | | lifetime `'a` required | consider changing type to `(&'a i32, &'a i32)` error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr index a51d9307d07..087c9eb389b 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr @@ -10,7 +10,7 @@ error[E0621]: explicit lifetime required in the type of `x` LL | fn foo<'a>(x: Ref, y: &mut Vec>) { | - consider changing the type of `x` to `Ref<'a, i32>` LL | y.push(x); //~ ERROR explicit lifetime - | ^ lifetime `'a` required + | ^^^^^^^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.nll.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.nll.stderr index e50fd74faf4..80192af2217 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.nll.stderr @@ -10,7 +10,7 @@ error[E0621]: explicit lifetime required in the type of `y` LL | fn foo<'a>(x: &mut Vec>, y: Ref) { | - consider changing the type of `y` to `Ref<'a, i32>` LL | x.push(y); //~ ERROR explicit lifetime - | ^ lifetime `'a` required + | ^^^^^^^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.nll.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.nll.stderr index 283192c6843..4b4fdde940f 100644 --- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(x: &mut Vec>, y: Ref) { | -------- -------- these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.nll.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.nll.stderr index 2ca202b402c..f55fd291249 100644 --- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.nll.stderr @@ -5,12 +5,13 @@ LL | let z = Ref { data: y.data }; | ^^^ error[E0623]: lifetime mismatch - --> $DIR/ex2c-push-inference-variable.rs:16:9 + --> $DIR/ex2c-push-inference-variable.rs:17:5 | LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... LL | let z = Ref { data: y.data }; - | ^ ...but data from `y` flows into `x` here +LL | x.push(z); //~ ERROR lifetime mismatch + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr index 712c25f8929..85b5f3e8900 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr @@ -5,12 +5,13 @@ LL | let b = Ref { data: y.data }; | ^^^ error[E0623]: lifetime mismatch - --> $DIR/ex2d-push-inference-variable-2.rs:16:9 + --> $DIR/ex2d-push-inference-variable-2.rs:18:5 | LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... -LL | let a: &mut Vec> = x; //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here +... +LL | a.push(b); + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr index 351966902a4..7e5182a5d30 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr @@ -5,12 +5,13 @@ LL | let b = Ref { data: y.data }; | ^^^ error[E0623]: lifetime mismatch - --> $DIR/ex2e-push-inference-variable-3.rs:16:9 + --> $DIR/ex2e-push-inference-variable-3.rs:18:5 | LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { | ------------ ------------ these two types are declared with different lifetimes... -LL | let a: &mut Vec> = x; //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here +... +LL | Vec::push(a, b); + | ^^^^^^^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.nll.stderr index da171577e2d..36317c4570b 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.nll.stderr @@ -5,12 +5,12 @@ LL | *v = x; //~ ERROR lifetime mismatch | ^ error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-2.rs:11:14 + --> $DIR/ex3-both-anon-regions-2.rs:12:5 | LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { - | ^^^^^^^^^ --- --- these two types are declared with different lifetimes... - | | - | ...but data from `x` flows here + | --- --- these two types are declared with different lifetimes... +LL | *v = x; //~ ERROR lifetime mismatch + | ^^^^^^ ...but data from `x` flows here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.nll.stderr index 102981977e5..61af34747ca 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.nll.stderr @@ -19,12 +19,12 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | ...but data flows into `z` here error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-3.rs:11:33 + --> $DIR/ex3-both-anon-regions-3.rs:11:36 | LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - | --- ^ --- these two types are declared with different lifetimes... - | | - | ...but data flows into `z` here + | --- ^ --- these two types are declared with different lifetimes... + | | + | ...but data flows into `z` here error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr index 9d1f6a3e36f..2a5729952e3 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr @@ -11,7 +11,7 @@ LL | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) | ------- ------- these two types are declared with different lifetimes... ... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr index 5df93fd5547..6efc8d3da06 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) { | ------- ------- these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr index cd602cf950b..0f555020822 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(mut x: Vec, y: Ref) { | --- --- these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr index 52c90839c32..4400644e7fb 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) { | ------ ------ these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr index d5bba6649a2..a0aa1e28d9b 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { | --- --- these two types are declared with different lifetimes... LL | y.push(z); //~ ERROR lifetime mismatch - | ^ ...but data from `z` flows into `y` here + | ^^^^^^^^^ ...but data from `z` flows into `y` here error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-fn-items.rs:11:3 diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr index 4d54f6fe037..5d4492701be 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | --- --- these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr index 0608b3be8b3..37b79cee72f 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(x:Box , y: Vec<&u8>, z: &u8) { | --- --- these two types are declared with different lifetimes... LL | y.push(z); //~ ERROR lifetime mismatch - | ^ ...but data from `z` flows into `y` here + | ^^^^^^^^^ ...but data from `z` flows into `y` here error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:11:3 diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions.nll.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions.nll.stderr index c25eedc770d..c11d81a4c13 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions.nll.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions.nll.stderr @@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | --- --- these two types are declared with different lifetimes... LL | x.push(y); //~ ERROR lifetime mismatch - | ^ ...but data from `y` flows into `x` here + | ^^^^^^^^^ ...but data from `y` flows into `x` here error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 840b4071a87..d713a37fa9f 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -24,14 +24,19 @@ LL | | }); = note: where '_#1r: '_#2r error[E0623]: lifetime mismatch - --> $DIR/propagate-approximated-ref.rs:53:29 + --> $DIR/propagate-approximated-ref.rs:53:5 | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ------- ------- - | | - | these two types are declared with different lifetimes... -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ^^^^^^^ ...but data from `cell_a` flows into `cell_b` here +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ------- ------- + | | + | these two types are declared with different lifetimes... +LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { +LL | | //~^ ERROR lifetime mismatch +LL | | +LL | | // Only works if 'x: 'y: +LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll +LL | | }); + | |______^ ...but data from `cell_a` flows into `cell_b` here note: No external requirements --> $DIR/propagate-approximated-ref.rs:52:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index cf5f4d415b6..f6ad6e46c62 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -24,14 +24,19 @@ LL | | }); = note: where '_#1r: '_#2r error[E0623]: lifetime mismatch - --> $DIR/propagate-approximated-val.rs:46:29 + --> $DIR/propagate-approximated-val.rs:46:5 | -LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ------- ------- - | | - | these two types are declared with different lifetimes... -LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - | ^^^^^^ ...but data from `cell_a` flows into `cell_b` here +LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ------- ------- + | | + | these two types are declared with different lifetimes... +LL | / establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { +LL | | //~^ ERROR lifetime mismatch +LL | | +LL | | // Only works if 'x: 'y: +LL | | demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to nll +LL | | }); + | |______^ ...but data from `cell_a` flows into `cell_b` here note: No external requirements --> $DIR/propagate-approximated-val.rs:45:1