Skip to content

Commit 0c388b0

Browse files
matthewjasperlqd
authored andcommitted
Report mismatched type errors for bound region errors in NLL
1 parent 5e6027c commit 0c388b0

19 files changed

+154
-59
lines changed

compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use rustc_infer::infer::canonical::Canonical;
2+
use rustc_infer::traits::ObligationCause;
3+
use rustc_middle::ty::error::TypeError;
24
use rustc_middle::ty::{self, Ty, TypeFoldable};
35
use rustc_span::Span;
46
use rustc_trait_selection::traits::query::type_op;
@@ -32,14 +34,33 @@ impl UniverseInfo<'tcx> {
3234
UniverseInfo(UniverseInfoInner::RelateTys { expected, found })
3335
}
3436

35-
crate fn _report_error(
37+
crate fn report_error(
3638
&self,
37-
_mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
39+
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
3840
_placeholder: ty::PlaceholderRegion,
3941
_error_element: RegionElement,
40-
_span: Span,
42+
span: Span,
4143
) {
42-
todo!();
44+
// FIXME: improve this error message
45+
match self.0 {
46+
UniverseInfoInner::RelateTys { expected, found } => {
47+
let body_id = mbcx.infcx.tcx.hir().local_def_id_to_hir_id(mbcx.mir_def_id());
48+
let err = mbcx.infcx.report_mismatched_types(
49+
&ObligationCause::misc(span, body_id),
50+
expected,
51+
found,
52+
TypeError::RegionsPlaceholderMismatch,
53+
);
54+
err.buffer(&mut mbcx.errors_buffer);
55+
}
56+
UniverseInfoInner::TypeOp(_) | UniverseInfoInner::Other => {
57+
mbcx.infcx
58+
.tcx
59+
.sess
60+
.struct_span_err(span, "higher-ranked subtype error")
61+
.buffer(&mut mbcx.errors_buffer);
62+
}
63+
}
4364
}
4465
}
4566

compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
223223
error_vid,
224224
);
225225

226-
// FIXME: improve this error message
227-
self.infcx
228-
.tcx
229-
.sess
230-
.struct_span_err(span, "higher-ranked subtype error")
231-
.buffer(&mut self.errors_buffer);
226+
let universe = placeholder.universe;
227+
let universe_info = self.regioncx.universe_info(universe);
228+
229+
universe_info.report_error(self, placeholder, error_element, span);
232230
}
233231

234232
RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {

compiler/rustc_mir/src/borrow_check/region_infer/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub struct RegionInferenceContext<'tcx> {
8585
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
8686

8787
/// Map universe indexes to information on why we created it.
88-
_universe_causes: IndexVec<ty::UniverseIndex, UniverseInfo<'tcx>>,
88+
universe_causes: IndexVec<ty::UniverseIndex, UniverseInfo<'tcx>>,
8989

9090
/// Contains the minimum universe of any variable within the same
9191
/// SCC. We will ensure that no SCC contains values that are not
@@ -297,7 +297,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
297297
member_constraints,
298298
member_constraints_applied: Vec::new(),
299299
closure_bounds_mapping,
300-
_universe_causes: universe_causes,
300+
universe_causes,
301301
scc_universes,
302302
scc_representatives,
303303
scc_values,
@@ -2143,6 +2143,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
21432143

21442144
categorized_path.remove(0)
21452145
}
2146+
2147+
crate fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
2148+
self.universe_causes[universe].clone()
2149+
}
21462150
}
21472151

21482152
impl<'tcx> RegionDefinition<'tcx> {

src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,33 @@ LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
2121
|
2222
= help: consider replacing `'x` with `'static`
2323

24-
error: higher-ranked subtype error
24+
error[E0308]: mismatched types
2525
--> $DIR/expect-fn-supply-fn.rs:32:49
2626
|
2727
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
28-
| ^
28+
| ^ one type is more general than the other
29+
|
30+
= note: expected fn pointer `for<'r> fn(&'r u32)`
31+
found fn pointer `fn(&u32)`
2932

30-
error: higher-ranked subtype error
33+
error[E0308]: mismatched types
3134
--> $DIR/expect-fn-supply-fn.rs:39:50
3235
|
3336
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
34-
| ^
37+
| ^ one type is more general than the other
38+
|
39+
= note: expected fn pointer `fn(&'x u32)`
40+
found fn pointer `for<'r> fn(&'r u32)`
3541

36-
error: higher-ranked subtype error
42+
error[E0308]: mismatched types
3743
--> $DIR/expect-fn-supply-fn.rs:48:50
3844
|
3945
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
40-
| ^
46+
| ^ one type is more general than the other
47+
|
48+
= note: expected fn pointer `fn(&u32)`
49+
found fn pointer `for<'r> fn(&'r u32)`
4150

4251
error: aborting due to 5 previous errors
4352

53+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/hr-subtype.rs:45:13
33
|
44
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
66
...
77
LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
88
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
99
| |_____________________________________________- in this macro invocation
1010
|
11+
= note: expected enum `Option<for<'r, 's> fn(&'r u32, &'s u32) -> &'r u32>`
12+
found enum `Option<for<'r> fn(&'r u32, &'r u32) -> &'r u32>`
1113
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
1214

1315
error: aborting due to previous error
1416

17+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/hr-subtype.rs:45:13
33
|
44
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
66
...
77
LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
88
LL | | fn(&'x u32)) }
99
| |______________- in this macro invocation
1010
|
11+
= note: expected enum `Option<for<'r> fn(&'r u32)>`
12+
found enum `Option<fn(&u32)>`
1113
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
1214

1315
error: aborting due to previous error
1416

17+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/hr-subtype.rs:45:13
33
|
44
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
66
...
77
LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
88
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
99
| |__________________________________- in this macro invocation
1010
|
11+
= note: expected enum `Option<for<'r, 's> fn(Inv<'r>, Inv<'s>)>`
12+
found enum `Option<for<'r> fn(Inv<'r>, Inv<'r>)>`
1113
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
1214

13-
error: higher-ranked subtype error
15+
error[E0308]: mismatched types
1416
--> $DIR/hr-subtype.rs:45:13
1517
|
1618
LL | gimme::<$t1>(None::<$t2>);
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
1820
...
1921
LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
2022
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
2123
| |__________________________________- in this macro invocation
2224
|
25+
= note: expected enum `Option<for<'r, 's> fn(Inv<'r>, Inv<'s>)>`
26+
found enum `Option<for<'r> fn(Inv<'r>, Inv<'r>)>`
2327
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
2428

2529
error: aborting due to 2 previous errors
2630

31+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/hrtb-exists-forall-fn.rs:17:12
33
|
44
LL | let _: for<'b> fn(&'b u32) = foo();
5-
| ^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'b> fn(&'b u32)`
8+
found fn pointer `fn(&u32)`
69

710
error: aborting due to previous error
811

12+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/old-lub-glb-hr-noteq1.rs:11:14
33
|
44
LL | _ => y,
5-
| ^
5+
| ^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'r, 's> fn(&'r u8, &'s u8) -> &'r u8`
8+
found fn pointer `for<'r> fn(&'r u8, &'r u8) -> &'r u8`
69

710
error: aborting due to previous error
811

12+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/nll/relate_tys/fn-subtype.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
fn main() {
88
let x: fn(&'static ()) = |_| {};
9-
let y: for<'a> fn(&'a ()) = x; //~ ERROR higher-ranked subtype error
9+
let y: for<'a> fn(&'a ()) = x; //~ ERROR mismatched types [E0308]
1010
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/fn-subtype.rs:9:33
33
|
44
LL | let y: for<'a> fn(&'a ()) = x;
5-
| ^
5+
| ^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'r> fn(&'r ())`
8+
found fn pointer `fn(&())`
69

710
error: aborting due to previous error
811

12+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ fn make_it() -> for<'a> fn(&'a u32, &'a u32) -> &'a u32 {
1212

1313
fn foo() {
1414
let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
15-
//~^ ERROR higher-ranked subtype error
15+
//~^ ERROR mismatched types [E0308]
1616
drop(a);
1717
}
1818

1919
fn bar() {
2020
// The code path for patterns is mildly different, so go ahead and
2121
// test that too:
2222
let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
23-
//~^ ERROR higher-ranked subtype error
23+
//~^ ERROR mismatched types [E0308]
2424
}
2525

26-
fn main() { }
26+
fn main() {}
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/hr-fn-aaa-as-aba.rs:14:58
33
|
44
LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
5-
| ^^^^^^^^^
5+
| ^^^^^^^^^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'r, 's> fn(&'r u32, &'s u32) -> &'r u32`
8+
found fn pointer `for<'a> fn(&'a u32, &'a u32) -> &'a u32`
69

7-
error: higher-ranked subtype error
10+
error[E0308]: mismatched types
811
--> $DIR/hr-fn-aaa-as-aba.rs:22:12
912
|
1013
LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
15+
|
16+
= note: expected fn pointer `for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32`
17+
found fn pointer `for<'r> fn(&'r u32, &'r u32) -> &'r u32`
1218

1319
error: aborting due to 2 previous errors
1420

21+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/nll/relate_tys/universe-violation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ fn make_it() -> fn(&'static u32) -> &'static u32 {
1212

1313
fn main() {
1414
let a: fn(_) -> _ = make_it();
15-
let b: fn(&u32) -> &u32 = a; //~ ERROR higher-ranked subtype error
15+
let b: fn(&u32) -> &u32 = a; //~ ERROR mismatched types [E0308]
1616
drop(a);
1717
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: higher-ranked subtype error
1+
error[E0308]: mismatched types
22
--> $DIR/universe-violation.rs:15:31
33
|
44
LL | let b: fn(&u32) -> &u32 = a;
5-
| ^
5+
| ^ one type is more general than the other
6+
|
7+
= note: expected fn pointer `for<'r> fn(&'r u32) -> &'r u32`
8+
found fn pointer `fn(&u32) -> &u32`
69

710
error: aborting due to previous error
811

12+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,24 @@ LL | a(x, y);
2727
= note: mutable references are invariant over their type parameter
2828
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
2929

30-
error: higher-ranked subtype error
30+
error[E0308]: mismatched types
3131
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12
3232
|
3333
LL | let _: fn(&mut &isize, &mut &isize) = a;
34-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
35+
|
36+
= note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
37+
found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
3538

36-
error: higher-ranked subtype error
39+
error[E0308]: mismatched types
3740
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12
3841
|
3942
LL | let _: fn(&mut &isize, &mut &isize) = a;
40-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
44+
|
45+
= note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
46+
found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
4147

4248
error: aborting due to 4 previous errors
4349

50+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,33 @@ LL | a(x, y, z);
2727
= note: mutable references are invariant over their type parameter
2828
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
2929

30-
error: higher-ranked subtype error
30+
error[E0308]: mismatched types
3131
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
3232
|
3333
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
34-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
35+
|
36+
= note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
37+
found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
3538

36-
error: higher-ranked subtype error
39+
error[E0308]: mismatched types
3740
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
3841
|
3942
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
40-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
44+
|
45+
= note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
46+
found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
4147

42-
error: higher-ranked subtype error
48+
error[E0308]: mismatched types
4349
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
4450
|
4551
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
46-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
53+
|
54+
= note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
55+
found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
4756

4857
error: aborting due to 5 previous errors
4958

59+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)