Skip to content

Commit dd748cb

Browse files
Check normalized call signature for WF in mir typeck
1 parent 27d8a57 commit dd748cb

7 files changed

+134
-2
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14131413
ConstraintCategory::Boring,
14141414
);
14151415
let sig = self.normalize(sig, term_location);
1416+
// HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))`
1417+
// with built-in `Fn` implementations, since the impl may not be
1418+
// well-formed itself.
1419+
self.prove_predicates(
1420+
sig.inputs_and_output.iter().map(|ty| {
1421+
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
1422+
ty.into(),
1423+
)))
1424+
}),
1425+
term_location.to_locations(),
1426+
ConstraintCategory::Boring,
1427+
);
14161428
self.check_call_dest(body, term, &sig, *destination, *target, term_location);
14171429

14181430
// The ordinary liveness rules will ensure that all

tests/ui/higher-ranked/trait-bounds/issue-59311.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ where
1717
v.t(|| {});
1818
//~^ ERROR: higher-ranked lifetime error
1919
//~| ERROR: higher-ranked lifetime error
20+
//~| ERROR: higher-ranked lifetime error
2021
}
2122

2223
fn main() {}

tests/ui/higher-ranked/trait-bounds/issue-59311.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ LL | v.t(|| {});
66
|
77
= note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed`
88

9+
error: higher-ranked lifetime error
10+
--> $DIR/issue-59311.rs:17:5
11+
|
12+
LL | v.t(|| {});
13+
| ^^^^^^^^^^
14+
|
15+
= note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed`
16+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
17+
918
error: higher-ranked lifetime error
1019
--> $DIR/issue-59311.rs:17:9
1120
|
@@ -14,5 +23,5 @@ LL | v.t(|| {});
1423
|
1524
= note: could not prove `for<'a> &'a V: 'static`
1625

17-
error: aborting due to 2 previous errors
26+
error: aborting due to 3 previous errors
1827

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// <https://github.com/rust-lang/rust/issues/114936>
2+
fn whoops(
3+
s: String,
4+
f: impl for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0]),
5+
) -> &'static str
6+
{
7+
f(&s).0
8+
//~^ ERROR `s` does not live long enough
9+
}
10+
11+
// <https://github.com/rust-lang/rust/issues/118876>
12+
fn extend<T>(input: &T) -> &'static T {
13+
struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]);
14+
let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
15+
n(input).0
16+
//~^ ERROR borrowed data escapes outside of function
17+
}
18+
19+
// <https://github.com/rust-lang/rust/issues/118876>
20+
fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
21+
struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]);
22+
let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
23+
n(input).0
24+
//~^ ERROR borrowed data escapes outside of function
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error[E0597]: `s` does not live long enough
2+
--> $DIR/check-normalized-sig-for-wf.rs:7:7
3+
|
4+
LL | s: String,
5+
| - binding `s` declared here
6+
...
7+
LL | f(&s).0
8+
| --^^-
9+
| | |
10+
| | borrowed value does not live long enough
11+
| argument requires that `s` is borrowed for `'static`
12+
LL |
13+
LL | }
14+
| - `s` dropped here while still borrowed
15+
16+
error[E0521]: borrowed data escapes outside of function
17+
--> $DIR/check-normalized-sig-for-wf.rs:15:5
18+
|
19+
LL | fn extend<T>(input: &T) -> &'static T {
20+
| ----- - let's call the lifetime of this reference `'1`
21+
| |
22+
| `input` is a reference that is only valid in the function body
23+
...
24+
LL | n(input).0
25+
| ^^^^^^^^
26+
| |
27+
| `input` escapes the function body here
28+
| argument requires that `'1` must outlive `'static`
29+
30+
error[E0521]: borrowed data escapes outside of function
31+
--> $DIR/check-normalized-sig-for-wf.rs:23:5
32+
|
33+
LL | fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
34+
| -- ----- `input` is a reference that is only valid in the function body
35+
| |
36+
| lifetime `'a` defined here
37+
...
38+
LL | n(input).0
39+
| ^^^^^^^^
40+
| |
41+
| `input` escapes the function body here
42+
| argument requires that `'a` must outlive `'static`
43+
44+
error: aborting due to 3 previous errors
45+
46+
Some errors have detailed explanations: E0521, E0597.
47+
For more information about an error, try `rustc --explain E0521`.

tests/ui/nll/missing-universe-cause-issue-114907.rs

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ fn main() {
3333
accept(callback);
3434
//~^ ERROR mismatched types
3535
//~| ERROR mismatched types
36+
//~| ERROR mismatched types
37+
//~| ERROR implementation of `FnOnce` is not general enough
3638
//~| ERROR implementation of `FnOnce` is not general enough
3739
//~| ERROR implementation of `FnOnce` is not general enough
3840
//~| ERROR higher-ranked subtype error

tests/ui/nll/missing-universe-cause-issue-114907.stderr

+35-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,40 @@ help: consider specifying the type of the closure parameters
6363
LL | let callback = |_: &_| {};
6464
| ~~~~~~~
6565

66+
error: implementation of `FnOnce` is not general enough
67+
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
68+
|
69+
LL | accept(callback);
70+
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
71+
|
72+
= note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
73+
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
74+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
75+
76+
error[E0308]: mismatched types
77+
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
78+
|
79+
LL | accept(callback);
80+
| ^^^^^^^^^^^^^^^^ one type is more general than the other
81+
|
82+
= note: expected trait `for<'a> FnOnce(&'a ())`
83+
found trait `FnOnce(&())`
84+
note: this closure does not fulfill the lifetime requirements
85+
--> $DIR/missing-universe-cause-issue-114907.rs:32:20
86+
|
87+
LL | let callback = |_| {};
88+
| ^^^
89+
note: the lifetime requirement is introduced here
90+
--> $DIR/missing-universe-cause-issue-114907.rs:20:21
91+
|
92+
LL | struct Handshake<R: Role> {
93+
| ^^^^
94+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
95+
help: consider specifying the type of the closure parameters
96+
|
97+
LL | let callback = |_: &_| {};
98+
| ~~~~~~~
99+
66100
error: higher-ranked subtype error
67101
--> $DIR/missing-universe-cause-issue-114907.rs:33:21
68102
|
@@ -77,6 +111,6 @@ LL | accept(callback);
77111
|
78112
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
79113

80-
error: aborting due to 6 previous errors
114+
error: aborting due to 8 previous errors
81115

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

0 commit comments

Comments
 (0)