Skip to content

Commit eaaee52

Browse files
authored
Rollup merge of rust-lang#56746 - pnkfelix:issue-56537-add-test-of-closure-using-region-from-containing-fn, r=nikomatsakis
Add test of current behavior (infer free region within closure body) This behavior was previously not encoded in our test suite. it is pretty important that we test this behavior. In particular, in rust-lang#56537 I had proposed expanding the lifetime elision rules so that they would apply to some of the cases encoded in this test, which would cause them to start failing to compile successfully (because the lifetime attached to the return type would start being treated as connected to the lifetime on the input parameter to the lambda expression, which is explicitly *not* what the code wants in this particular case). In other words, I am trying to ensure that anyone who tries such experiments with lifetime elision in the future quickly finds out why we don't support lifetime elision on lambda expressions (at least not in the naive manner described on rust-lang#56537).
2 parents 4c838e9 + 29e7ca9 commit eaaee52

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// This is a collection of examples where a function's formal
2+
// parameter has an explicit lifetime and a closure within that
3+
// function returns that formal parameter. The closure's return type,
4+
// to be correctly inferred, needs to include the lifetime introduced
5+
// by the function.
6+
//
7+
// This works today, which precludes changing things so that closures
8+
// follow the same lifetime-elision rules used elsehwere. See
9+
// rust-lang/rust#56537
10+
11+
// compile-pass
12+
// We are already testing NLL explicitly via the revision system below.
13+
// ignore-compare-mode-nll
14+
15+
// revisions: ll nll migrate
16+
//[ll] compile-flags:-Zborrowck=ast
17+
//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
18+
//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows
19+
20+
fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
21+
let free_dumb = |_x| { p }; // no type annotation at all
22+
let hello = format!("Hello");
23+
free_dumb(&hello)
24+
}
25+
26+
fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
27+
let free_dumb = |_x| -> &str { p }; // type annotation on the return type
28+
let hello = format!("Hello");
29+
free_dumb(&hello)
30+
}
31+
32+
fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
33+
let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
34+
let hello = format!("Hello");
35+
free_dumb(&hello)
36+
}
37+
38+
fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
39+
let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
40+
let hello = format!("Hello");
41+
free_dumb(&hello)
42+
}
43+
44+
fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
45+
let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
46+
let hello = format!("Hello");
47+
free_dumb(&hello)
48+
}
49+
50+
fn main() {
51+
let world = format!("World");
52+
let w1: &str = {
53+
let hello = format!("He11o");
54+
willy_no_annot(&world, &hello)
55+
};
56+
let w2: &str = {
57+
let hello = format!("He22o");
58+
willy_ret_type_annot(&world, &hello)
59+
};
60+
let w3: &str = {
61+
let hello = format!("He33o");
62+
willy_ret_region_annot(&world, &hello)
63+
};
64+
let w4: &str = {
65+
let hello = format!("He44o");
66+
willy_arg_type_ret_type_annot(&world, &hello)
67+
};
68+
let w5: &str = {
69+
let hello = format!("He55o");
70+
willy_arg_type_ret_region_annot(&world, &hello)
71+
};
72+
assert_eq!((w1, w2, w3, w4, w5),
73+
("World","World","World","World","World"));
74+
}

0 commit comments

Comments
 (0)