Skip to content

Commit 78395bb

Browse files
authored
Rollup merge of rust-lang#95607 - compiler-errors:issue-95272, r=Aaron1011
Note invariance reason for FnDef types Fixes rust-lang#95272. Is it worthwhile even printing a variance explanation here? Or should I try to track down which function parameter is responsible for the invariance? r? `@Aaron1011` since you wrote rust-lang#89336
2 parents c95357a + 2a129d4 commit 78395bb

File tree

31 files changed

+158
-113
lines changed

31 files changed

+158
-113
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
330330
ty::RawPtr(ty_mut) => {
331331
assert_eq!(ty_mut.mutbl, rustc_hir::Mutability::Mut);
332332
(
333-
format!("a mutable pointer to {}", ty_mut.ty),
333+
format!("a mutable pointer to `{}`", ty_mut.ty),
334334
"mutable pointers are invariant over their type parameter".to_string(),
335335
)
336336
}
337337
ty::Ref(_, inner_ty, mutbl) => {
338338
assert_eq!(*mutbl, rustc_hir::Mutability::Mut);
339339
(
340-
format!("a mutable reference to {}", inner_ty),
340+
format!("a mutable reference to `{}`", inner_ty),
341341
"mutable references are invariant over their type parameter"
342342
.to_string(),
343343
)
@@ -351,10 +351,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
351351
let adt_desc = adt.descr();
352352

353353
let desc = format!(
354-
"the type {ty}, which makes the generic argument {generic_arg} invariant"
354+
"the type `{ty}`, which makes the generic argument `{generic_arg}` invariant"
355355
);
356356
let note = format!(
357-
"the {adt_desc} {base_ty} is invariant over the parameter {base_generic_arg}"
357+
"the {adt_desc} `{base_ty}` is invariant over the parameter `{base_generic_arg}`"
358+
);
359+
(desc, note)
360+
}
361+
ty::FnDef(def_id, _) => {
362+
let name = self.infcx.tcx.item_name(*def_id);
363+
let identity_substs =
364+
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
365+
let desc = format!("a function pointer to `{name}`");
366+
let note = format!(
367+
"the function `{name}` is invariant over the parameter `{}`",
368+
identity_substs[param_index as usize]
358369
);
359370
(desc, note)
360371
}

src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | (a, b)
1010
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
1111
|
1212
= help: consider adding the following bound: `'a: 'b`
13-
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
14-
= note: the struct Type<'a> is invariant over the parameter 'a
13+
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
14+
= note: the struct `Type<'a>` is invariant over the parameter `'a`
1515
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1616

1717
error: lifetime may not live long enough
@@ -26,8 +26,8 @@ LL | (a, b)
2626
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
2727
|
2828
= help: consider adding the following bound: `'b: 'a`
29-
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
30-
= note: the struct Type<'a> is invariant over the parameter 'a
29+
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
30+
= note: the struct `Type<'a>` is invariant over the parameter `'a`
3131
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
3232

3333
help: `'a` and `'b` must be the same: replace one with the other

src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | let a = bar(f, x);
1010
| ^^^^^^^^^ argument requires that `'a` must outlive `'b`
1111
|
1212
= help: consider adding the following bound: `'a: 'b`
13-
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
14-
= note: the struct Type<'a> is invariant over the parameter 'a
13+
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
14+
= note: the struct `Type<'a>` is invariant over the parameter `'a`
1515
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1616

1717
error: lifetime may not live long enough
@@ -26,8 +26,8 @@ LL | let b = bar(f, y);
2626
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
2727
|
2828
= help: consider adding the following bound: `'b: 'a`
29-
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
30-
= note: the struct Type<'a> is invariant over the parameter 'a
29+
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
30+
= note: the struct `Type<'a>` is invariant over the parameter `'a`
3131
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
3232

3333
help: `'a` and `'b` must be the same: replace one with the other

src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
77
LL | bar(foo, x)
88
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
99
|
10-
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
11-
= note: the struct Type<'a> is invariant over the parameter 'a
10+
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
11+
= note: the struct `Type<'a>` is invariant over the parameter `'a`
1212
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1313

1414
error: aborting due to previous error

src/test/ui/c-variadic/variadic-ffi-4.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f
88
LL | ap
99
| ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f`
1010
|
11-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
12-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
11+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
12+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
1313
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1414

1515
error: lifetime may not live long enough
@@ -22,8 +22,8 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f
2222
LL | ap
2323
| ^^ function was supposed to return data with lifetime `'f` but it is returning data with lifetime `'1`
2424
|
25-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
26-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
25+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
26+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
2727
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
2828

2929
error: lifetime may not live long enough
@@ -34,8 +34,8 @@ LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'stati
3434
LL | ap
3535
| ^^ returning this value requires that `'1` must outlive `'static`
3636
|
37-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
38-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
37+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
38+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
3939
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
4040

4141
error: lifetime may not live long enough
@@ -57,8 +57,8 @@ LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut
5757
LL | *ap0 = ap1;
5858
| ^^^^ assignment requires that `'1` must outlive `'2`
5959
|
60-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
61-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
60+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
61+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
6262
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
6363

6464
error: lifetime may not live long enough
@@ -71,8 +71,8 @@ LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut
7171
LL | *ap0 = ap1;
7272
| ^^^^ assignment requires that `'2` must outlive `'1`
7373
|
74-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
75-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
74+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
75+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
7676
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
7777

7878
error: lifetime may not live long enough
@@ -85,7 +85,7 @@ LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut
8585
LL | ap0 = &mut ap1;
8686
| ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
8787
|
88-
= note: requirement occurs because of a mutable reference to VaListImpl<'_>
88+
= note: requirement occurs because of a mutable reference to `VaListImpl<'_>`
8989
= note: mutable references are invariant over their type parameter
9090
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
9191

@@ -99,7 +99,7 @@ LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut
9999
LL | ap0 = &mut ap1;
100100
| ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
101101
|
102-
= note: requirement occurs because of a mutable reference to VaListImpl<'_>
102+
= note: requirement occurs because of a mutable reference to `VaListImpl<'_>`
103103
= note: mutable references are invariant over their type parameter
104104
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
105105

@@ -127,8 +127,8 @@ LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut
127127
LL | *ap0 = ap1.clone();
128128
| ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
129129
|
130-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
131-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
130+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
131+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
132132
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
133133

134134
error: lifetime may not live long enough
@@ -141,8 +141,8 @@ LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut
141141
LL | *ap0 = ap1.clone();
142142
| ^^^^^^^^^^^ argument requires that `'2` must outlive `'1`
143143
|
144-
= note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant
145-
= note: the struct VaListImpl<'f> is invariant over the parameter 'f
144+
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
145+
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
146146
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
147147

148148
error: aborting due to 11 previous errors

src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ LL | | fn(Inv<'y>)) }
1313
| |______________- in this macro invocation
1414
|
1515
= help: consider adding the following bound: `'x: 'y`
16-
= note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant
17-
= note: the struct Inv<'a> is invariant over the parameter 'a
16+
= note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant
17+
= note: the struct `Inv<'a>` is invariant over the parameter `'a`
1818
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1919
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
2020

@@ -33,8 +33,8 @@ LL | | fn(Inv<'y>)) }
3333
| |______________- in this macro invocation
3434
|
3535
= help: consider adding the following bound: `'x: 'y`
36-
= note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant
37-
= note: the struct Inv<'a> is invariant over the parameter 'a
36+
= note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant
37+
= note: the struct `Inv<'a>` is invariant over the parameter `'a`
3838
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
3939
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
4040

src/test/ui/match/match-ref-mut-invariance.nll.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | match self.0 { ref mut x => x }
99
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
1010
|
1111
= help: consider adding the following bound: `'a: 'b`
12-
= note: requirement occurs because of a mutable reference to &i32
12+
= note: requirement occurs because of a mutable reference to `&i32`
1313
= note: mutable references are invariant over their type parameter
1414
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1515

src/test/ui/match/match-ref-mut-let-invariance.nll.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | x
1010
| ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
1111
|
1212
= help: consider adding the following bound: `'a: 'b`
13-
= note: requirement occurs because of a mutable reference to &i32
13+
= note: requirement occurs because of a mutable reference to `&i32`
1414
= note: mutable references are invariant over their type parameter
1515
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
1616

src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ LL | | });
5252
| |______`cell_a` escapes the function body here
5353
| argument requires that `'a` must outlive `'static`
5454
|
55-
= note: requirement occurs because of the type Cell<&'_#10r u32>, which makes the generic argument &'_#10r u32 invariant
56-
= note: the struct Cell<T> is invariant over the parameter T
55+
= note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant
56+
= note: the struct `Cell<T>` is invariant over the parameter `T`
5757
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
5858

5959
error: aborting due to previous error

src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ LL | | });
5252
| |______`cell_a` escapes the function body here
5353
| argument requires that `'a` must outlive `'static`
5454
|
55-
= note: requirement occurs because of the type Cell<&'_#11r u32>, which makes the generic argument &'_#11r u32 invariant
56-
= note: the struct Cell<T> is invariant over the parameter T
55+
= note: requirement occurs because of the type `Cell<&'_#11r u32>`, which makes the generic argument `&'_#11r u32` invariant
56+
= note: the struct `Cell<T>` is invariant over the parameter `T`
5757
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
5858

5959
error: aborting due to previous error

src/test/ui/nll/issue-95272.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(nll)]
2+
3+
use std::cell::Cell;
4+
5+
fn check<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>)
6+
where
7+
'a: 'b,
8+
{
9+
}
10+
11+
fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
12+
let f = check;
13+
//~^ ERROR lifetime may not live long enough
14+
f(x, y);
15+
}
16+
17+
fn main() {}

src/test/ui/nll/issue-95272.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/issue-95272.rs:12:13
3+
|
4+
LL | fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
5+
| -- -- lifetime `'b` defined here
6+
| |
7+
| lifetime `'a` defined here
8+
LL | let f = check;
9+
| ^^^^^ assignment requires that `'a` must outlive `'b`
10+
|
11+
= help: consider adding the following bound: `'a: 'b`
12+
= note: requirement occurs because of a function pointer to `check`
13+
= note: the function `check` is invariant over the parameter `'a`
14+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
15+
16+
error: aborting due to previous error
17+

src/test/ui/nll/type-check-pointer-coercions.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ LL | x
3434
| ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
3535
|
3636
= help: consider adding the following bound: `'b: 'a`
37-
= note: requirement occurs because of a mutable pointer to &i32
37+
= note: requirement occurs because of a mutable pointer to `&i32`
3838
= note: mutable pointers are invariant over their type parameter
3939
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
4040

@@ -50,7 +50,7 @@ LL | x
5050
| ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
5151
|
5252
= help: consider adding the following bound: `'a: 'b`
53-
= note: requirement occurs because of a mutable pointer to &i32
53+
= note: requirement occurs because of a mutable pointer to `&i32`
5454
= note: mutable pointers are invariant over their type parameter
5555
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
5656

0 commit comments

Comments
 (0)