Skip to content

Commit 39b39da

Browse files
committed
Stop proving outlives constraints on regions we already reported errors on
1 parent a04ac26 commit 39b39da

25 files changed

+97
-246
lines changed

compiler/rustc_borrowck/src/nll.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
125125
placeholder_indices,
126126
placeholder_index_to_region: _,
127127
liveness_constraints,
128-
outlives_constraints,
129-
member_constraints,
128+
mut outlives_constraints,
129+
mut member_constraints,
130130
universe_causes,
131131
type_tests,
132132
} = constraints;
@@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
144144
&universal_region_relations,
145145
);
146146

147+
if let Some(guar) = universal_regions.tainted_by_errors() {
148+
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
149+
// outlives bounds that we may end up checking.
150+
outlives_constraints = Default::default();
151+
member_constraints = Default::default();
152+
153+
// Also taint the entire scope.
154+
infcx.set_tainted_by_errors(guar);
155+
}
156+
147157
let mut regioncx = RegionInferenceContext::new(
148158
infcx,
149159
var_origins,

compiler/rustc_borrowck/src/universal_regions.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T
2929
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
3030
use rustc_middle::{bug, span_bug};
3131
use rustc_span::symbol::{kw, sym};
32-
use rustc_span::Symbol;
32+
use rustc_span::{ErrorGuaranteed, Symbol};
33+
use std::cell::Cell;
3334
use std::iter;
3435

3536
use crate::renumber::RegionCtxt;
@@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> {
186187

187188
/// The vid assigned to `'static`. Used only for diagnostics.
188189
pub fr_static: RegionVid,
190+
191+
/// Whether we've encountered an error region. If we have, cancel all
192+
/// outlives errors, as they are likely bogus.
193+
pub tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
189194
}
190195

191196
#[derive(Debug, PartialEq)]
@@ -408,6 +413,10 @@ impl<'tcx> UniversalRegions<'tcx> {
408413
}
409414
}
410415
}
416+
417+
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
418+
self.indices.tainted_by_errors.get()
419+
}
411420
}
412421

413422
struct UniversalRegionsBuilder<'cx, 'tcx> {
@@ -663,7 +672,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
663672
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
664673
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
665674

666-
UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
675+
UniversalRegionIndices {
676+
indices: global_mapping.chain(arg_mapping).collect(),
677+
fr_static,
678+
tainted_by_errors: Cell::new(None),
679+
}
667680
}
668681

669682
fn compute_inputs_and_output(
@@ -868,7 +881,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
868881
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
869882
if let ty::ReVar(..) = *r {
870883
r.as_var()
871-
} else if r.is_error() {
884+
} else if let ty::ReError(guar) = *r {
885+
self.tainted_by_errors.set(Some(guar));
872886
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
873887
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
874888
// errors are being emitted and 2) it leaves the happy path unaffected.
+8-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
// This test ensures that it's not crashing rustdoc.
22

33
pub struct Foo<'a, 'b, T> {
4-
field1: dyn Bar<'a, 'b,>,
4+
field1: dyn Bar<'a, 'b>,
55
//~^ ERROR
66
//~| ERROR
7+
//~| ERROR
78
}
89

910
pub trait Bar<'x, 's, U>
10-
where U: 'x,
11-
Self:'x,
12-
Self:'s
13-
{}
11+
where
12+
U: 'x,
13+
Self: 'x,
14+
Self: 's,
15+
{
16+
}
+24-7
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
22
--> $DIR/unable-fulfill-trait.rs:4:17
33
|
4-
LL | field1: dyn Bar<'a, 'b,>,
4+
LL | field1: dyn Bar<'a, 'b>,
55
| ^^^ expected 1 generic argument
66
|
77
note: trait defined here, with 1 generic parameter: `U`
8-
--> $DIR/unable-fulfill-trait.rs:9:11
8+
--> $DIR/unable-fulfill-trait.rs:10:11
99
|
1010
LL | pub trait Bar<'x, 's, U>
1111
| ^^^ -
1212
help: add missing generic argument
1313
|
14-
LL | field1: dyn Bar<'a, 'b, U,>,
14+
LL | field1: dyn Bar<'a, 'b, U>,
1515
| +++
1616

1717
error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
1818
--> $DIR/unable-fulfill-trait.rs:4:13
1919
|
20-
LL | field1: dyn Bar<'a, 'b,>,
21-
| ^^^^^^^^^^^^^^^^
20+
LL | field1: dyn Bar<'a, 'b>,
21+
| ^^^^^^^^^^^^^^^
2222

23-
error: aborting due to 2 previous errors
23+
error[E0478]: lifetime bound not satisfied
24+
--> $DIR/unable-fulfill-trait.rs:4:13
25+
|
26+
LL | field1: dyn Bar<'a, 'b>,
27+
| ^^^^^^^^^^^^^^^
28+
|
29+
note: lifetime parameter instantiated with the lifetime `'b` as defined here
30+
--> $DIR/unable-fulfill-trait.rs:3:20
31+
|
32+
LL | pub struct Foo<'a, 'b, T> {
33+
| ^^
34+
note: but lifetime parameter must outlive the lifetime `'a` as defined here
35+
--> $DIR/unable-fulfill-trait.rs:3:16
36+
|
37+
LL | pub struct Foo<'a, 'b, T> {
38+
| ^^
39+
40+
error: aborting due to 3 previous errors
2441

25-
Some errors have detailed explanations: E0107, E0227.
42+
Some errors have detailed explanations: E0107, E0227, E0478.
2643
For more information about an error, try `rustc --explain E0107`.

tests/ui/associated-inherent-types/issue-109299.rs

-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d`
88
}
99

1010
fn test(_: Lexer::Cursor) {}
11-
//~^ ERROR: lifetime may not live long enough
1211

1312
fn main() {}

tests/ui/associated-inherent-types/issue-109299.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ LL | impl Lexer<'d> {
66
| |
77
| help: consider introducing lifetime `'d` here: `<'d>`
88

9-
error: lifetime may not live long enough
10-
--> $DIR/issue-109299.rs:10:1
11-
|
12-
LL | fn test(_: Lexer::Cursor) {}
13-
| ^^^^^^^^-^^^^^^^^^^^^^^^^
14-
| | |
15-
| | has type `Lexer<'1>::Cursor`
16-
| requires that `'1` must outlive `'static`
17-
18-
error: aborting due to 2 previous errors
9+
error: aborting due to 1 previous error
1910

2011
For more information about this error, try `rustc --explain E0261`.

tests/ui/borrowck/generic_const_early_param.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ struct DataWrapper<'static> {
55
//~^ ERROR invalid lifetime parameter name: `'static`
66
data: &'a [u8; Self::SIZE],
77
//~^ ERROR use of undeclared lifetime name `'a`
8-
//~^^ ERROR lifetime may not live long enough
98
}
109

1110
impl DataWrapper<'a> {

tests/ui/borrowck/generic_const_early_param.stderr

+2-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ LL | data: &'a [u8; Self::SIZE],
1414
| ^^ undeclared lifetime
1515

1616
error[E0261]: use of undeclared lifetime name `'a`
17-
--> $DIR/generic_const_early_param.rs:11:18
17+
--> $DIR/generic_const_early_param.rs:10:18
1818
|
1919
LL | impl DataWrapper<'a> {
2020
| - ^^ undeclared lifetime
@@ -30,13 +30,7 @@ LL | #![feature(generic_const_exprs)]
3030
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
3131
= note: `#[warn(incomplete_features)]` on by default
3232

33-
error: lifetime may not live long enough
34-
--> $DIR/generic_const_early_param.rs:6:20
35-
|
36-
LL | data: &'a [u8; Self::SIZE],
37-
| ^^^^^^^^^^ requires that `'_` must outlive `'static`
38-
39-
error: aborting due to 4 previous errors; 1 warning emitted
33+
error: aborting due to 3 previous errors; 1 warning emitted
4034

4135
Some errors have detailed explanations: E0261, E0262.
4236
For more information about an error, try `rustc --explain E0261`.

tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
99
//~^ ERROR missing generics for associated type
1010
//~^^ ERROR missing generics for associated type
1111
//~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
12-
//~| ERROR may not live long enough
1312
t
1413
}
1514
}

tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,7 @@ help: add missing lifetime argument
5151
LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
5252
| ++++
5353

54-
error: lifetime may not live long enough
55-
--> $DIR/gat-trait-path-missing-lifetime.rs:8:3
56-
|
57-
LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
58-
| ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
59-
| | |
60-
| | lifetime `'a` defined here
61-
| requires that `'a` must outlive `'static`
62-
63-
error: aborting due to 5 previous errors
54+
error: aborting due to 4 previous errors
6455

6556
Some errors have detailed explanations: E0046, E0049, E0107.
6657
For more information about an error, try `rustc --explain E0046`.

tests/ui/generic-associated-types/issue-70304.rs

-1
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,4 @@ fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
5252
pub fn main() {
5353
let doc = create_doc();
5454
let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
55-
//~^ ERROR: `doc` does not live long enough
5655
}

tests/ui/generic-associated-types/issue-70304.stderr

+2-16
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,7 @@ LL | type Cursor<'a>: DocCursor<'a>;
2727
= note: this bound is currently required to ensure that impls have maximum flexibility
2828
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
2929

30-
error[E0597]: `doc` does not live long enough
31-
--> $DIR/issue-70304.rs:54:59
32-
|
33-
LL | let doc = create_doc();
34-
| --- binding `doc` declared here
35-
LL | let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
36-
| ------------^^^^-
37-
| | |
38-
| | borrowed value does not live long enough
39-
| argument requires that `doc` is borrowed for `'static`
40-
LL |
41-
LL | }
42-
| - `doc` dropped here while still borrowed
43-
44-
error: aborting due to 4 previous errors
30+
error: aborting due to 3 previous errors
4531

46-
Some errors have detailed explanations: E0106, E0597, E0637.
32+
Some errors have detailed explanations: E0106, E0637.
4733
For more information about an error, try `rustc --explain E0106`.

tests/ui/generic-associated-types/issue-80433.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
2222
//~^ ERROR missing generics for associated type
2323
{
2424
for n in 0i16..100 {
25-
*dst.test_mut() = n.into(); //~ ERROR: cannot borrow
26-
//~^ ERROR: borrowed data escapes outside of function
25+
*dst.test_mut() = n.into();
2726
}
2827
}
2928

tests/ui/generic-associated-types/issue-80433.stderr

+2-26
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,6 @@ help: add missing lifetime argument
2525
LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output<'a> = &'a mut f32>)
2626
| ++++
2727

28-
error[E0499]: cannot borrow `*dst` as mutable more than once at a time
29-
--> $DIR/issue-80433.rs:25:10
30-
|
31-
LL | *dst.test_mut() = n.into();
32-
| ^^^-----------
33-
| |
34-
| `*dst` was mutably borrowed here in the previous iteration of the loop
35-
| argument requires that `*dst` is borrowed for `'static`
36-
37-
error[E0521]: borrowed data escapes outside of function
38-
--> $DIR/issue-80433.rs:25:10
39-
|
40-
LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
41-
| -- --- `dst` is a reference that is only valid in the function body
42-
| |
43-
| lifetime `'a` defined here
44-
...
45-
LL | *dst.test_mut() = n.into();
46-
| ^^^^^^^^^^^^^^
47-
| |
48-
| `dst` escapes the function body here
49-
| argument requires that `'a` must outlive `'static`
50-
51-
error: aborting due to 4 previous errors
28+
error: aborting due to 2 previous errors
5229

53-
Some errors have detailed explanations: E0107, E0499, E0521.
54-
For more information about an error, try `rustc --explain E0107`.
30+
For more information about this error, try `rustc --explain E0107`.
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// issue: 114146
22

3-
43
trait Foo {
54
fn bar<'other: 'a>() -> impl Sized + 'a {}
65
//~^ ERROR use of undeclared lifetime name `'a`
76
//~| ERROR use of undeclared lifetime name `'a`
8-
//~| ERROR expected generic lifetime parameter, found `'static`
97
}
108

119
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0261]: use of undeclared lifetime name `'a`
2-
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:20
2+
--> $DIR/bad-item-bound-within-rpitit-2.rs:4:20
33
|
44
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
55
| ^^ undeclared lifetime
@@ -14,7 +14,7 @@ LL | trait Foo<'a> {
1414
| ++++
1515

1616
error[E0261]: use of undeclared lifetime name `'a`
17-
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:42
17+
--> $DIR/bad-item-bound-within-rpitit-2.rs:4:42
1818
|
1919
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
2020
| ^^ undeclared lifetime
@@ -28,15 +28,6 @@ help: consider introducing lifetime `'a` here
2828
LL | trait Foo<'a> {
2929
| ++++
3030

31-
error[E0792]: expected generic lifetime parameter, found `'static`
32-
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:45
33-
|
34-
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
35-
| ------ ^^
36-
| |
37-
| cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
38-
39-
error: aborting due to 3 previous errors
31+
error: aborting due to 2 previous errors
4032

41-
Some errors have detailed explanations: E0261, E0792.
42-
For more information about an error, try `rustc --explain E0261`.
33+
For more information about this error, try `rustc --explain E0261`.

tests/ui/impl-trait/issues/issue-67830.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct Wrap<F>(F);
77

88
impl<A, B, F> MyFn<A> for Wrap<F>
99
where
10-
F: Fn(A) -> B
10+
F: Fn(A) -> B,
1111
{
1212
type Output = B;
1313

@@ -16,13 +16,10 @@ where
1616
}
1717
}
1818

19-
2019
struct A;
21-
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
20+
fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> {
2221
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
2322
Wrap(|a| Some(a).into_iter())
24-
//~^ ERROR implementation of `FnOnce` is not general enough
25-
//~| ERROR implementation of `FnOnce` is not general enough
2623
}
2724

2825
fn main() {}

0 commit comments

Comments
 (0)