Skip to content

Commit

Permalink
Rollup merge of #56746 - pnkfelix:issue-56537-add-test-of-closure-usi…
Browse files Browse the repository at this point in the history
…ng-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 #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 #56537).
  • Loading branch information
pietroalbini authored Dec 12, 2018
2 parents 7f82fe1 + 29e7ca9 commit d6814a3
Showing 1 changed file with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// This is a collection of examples where a function's formal
// parameter has an explicit lifetime and a closure within that
// function returns that formal parameter. The closure's return type,
// to be correctly inferred, needs to include the lifetime introduced
// by the function.
//
// This works today, which precludes changing things so that closures
// follow the same lifetime-elision rules used elsehwere. See
// rust-lang/rust#56537

// compile-pass
// We are already testing NLL explicitly via the revision system below.
// ignore-compare-mode-nll

// revisions: ll nll migrate
//[ll] compile-flags:-Zborrowck=ast
//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows

fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
let free_dumb = |_x| { p }; // no type annotation at all
let hello = format!("Hello");
free_dumb(&hello)
}

fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
let free_dumb = |_x| -> &str { p }; // type annotation on the return type
let hello = format!("Hello");
free_dumb(&hello)
}

fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
let hello = format!("Hello");
free_dumb(&hello)
}

fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
let hello = format!("Hello");
free_dumb(&hello)
}

fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
let hello = format!("Hello");
free_dumb(&hello)
}

fn main() {
let world = format!("World");
let w1: &str = {
let hello = format!("He11o");
willy_no_annot(&world, &hello)
};
let w2: &str = {
let hello = format!("He22o");
willy_ret_type_annot(&world, &hello)
};
let w3: &str = {
let hello = format!("He33o");
willy_ret_region_annot(&world, &hello)
};
let w4: &str = {
let hello = format!("He44o");
willy_arg_type_ret_type_annot(&world, &hello)
};
let w5: &str = {
let hello = format!("He55o");
willy_arg_type_ret_region_annot(&world, &hello)
};
assert_eq!((w1, w2, w3, w4, w5),
("World","World","World","World","World"));
}

0 comments on commit d6814a3

Please sign in to comment.