-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement support for generators #1378
Merged
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
ac34884
Implement support for generators
fzaiser 798af91
Fix tests
fzaiser 9ca6263
Fix generator codegen (different approach than enums)
fzaiser f8c06bb
Add tests (mostly taken from rustc)
fzaiser 229cf4d
Fix copyright headers
fzaiser b9838c0
Merge branch 'main' into generators
fzaiser 1443b5c
Small code simplification
fzaiser ca0c21f
Merge branch 'generators' of https://github.com/fzaiser/kani into gen…
fzaiser 1cabf67
Refactor: remove unnecessary Option
fzaiser 3005cca
Update comments
fzaiser f818b34
Merge branch 'main' into generators
fzaiser e269f4f
Fix merge issue
fzaiser 1826b5b
Address reviewer comments
fzaiser dd728ec
Merge branch 'main' into generators
fzaiser db2263c
Fix comment test
fzaiser 72d5d10
Improve tests
fzaiser de87147
Merge branch 'main' into generators
fzaiser 64f7af1
Address reviewer comments
fzaiser 88eaf1f
Check generator layout assumption only in one place
fzaiser daecbbf
Merge branch 'main' into generators
fzaiser 5864e9f
Make size_of or align_of fail for generators (because they are curren…
fzaiser File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
tests/kani/Generator/rustc-generator-tests/niche-in-generator-slow_fixme.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// | ||
// Modifications Copyright Kani Contributors | ||
// See GitHub history for details. | ||
|
||
// Copyright rustc Contributors | ||
// Adapted from rustc: https://github.com/rust-lang/rust/tree/5f98537eb7b5f42c246a52c550813c3cff336069/src/test/ui/generator/niche-in-generator.rs | ||
|
||
// Test that niche finding works with captured generator upvars. | ||
|
||
// run-pass | ||
|
||
#![feature(generators, generator_trait)] | ||
|
||
use std::ops::{Generator, GeneratorState}; | ||
use std::pin::Pin; | ||
|
||
use std::mem::size_of_val; | ||
|
||
fn take<T>(_: T) {} | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let x = false; | ||
let mut gen1 = || { | ||
yield; | ||
take(x); | ||
}; | ||
|
||
// FIXME: for some reason, these asserts are very hard for CBMC to figure out | ||
// Kani didn't terminate within 5 minutes. | ||
// assert_eq!(Pin::new(&mut gen1).resume(()), GeneratorState::Yielded(())); | ||
// assert_eq!(Pin::new(&mut gen1).resume(()), GeneratorState::Complete(())); | ||
assert!(false); // to make the test fail without taking forever | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
tests/kani/Generator/rustc-generator-tests/overlap-locals_fixme.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// | ||
// Modifications Copyright Kani Contributors | ||
// See GitHub history for details. | ||
|
||
// Copyright rustc Contributors | ||
// Adapted from rustc: https://github.com/rust-lang/rust/tree/5f98537eb7b5f42c246a52c550813c3cff336069/src/test/ui/generator/overlap-locals.rs | ||
|
||
// run-pass | ||
|
||
#![feature(generators)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a = || { | ||
{ | ||
let w: i32 = 4; | ||
yield; | ||
println!("{:?}", w); | ||
} | ||
{ | ||
let x: i32 = 5; | ||
yield; | ||
println!("{:?}", x); | ||
} | ||
{ | ||
let y: i32 = 6; | ||
yield; | ||
println!("{:?}", y); | ||
} | ||
{ | ||
let z: i32 = 7; | ||
yield; | ||
println!("{:?}", z); | ||
} | ||
}; | ||
|
||
// FIXME: size of generators does not work reliably (https://github.com/model-checking/kani/issues/1395) | ||
assert_eq!(8, std::mem::size_of_val(&a)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// | ||
// Modifications Copyright Kani Contributors | ||
// See GitHub history for details. | ||
|
||
// Copyright rustc Contributors | ||
// Adapted from rustc: https://github.com/rust-lang/rust/tree/5f98537eb7b5f42c246a52c550813c3cff336069/src/test/ui/generator/resume-arg-size.rs | ||
|
||
#![feature(generators, generator_trait)] | ||
|
||
use std::ops::{Generator, GeneratorState}; | ||
use std::pin::Pin; | ||
|
||
// run-pass | ||
|
||
use std::mem::size_of_val; | ||
|
||
#[kani::proof] | ||
fn main() { | ||
// Generator taking a `Copy`able resume arg. | ||
let mut gen_copy = |mut x: usize| { | ||
loop { | ||
drop(x); | ||
x = yield; | ||
} | ||
}; | ||
|
||
// Generator taking a non-`Copy` resume arg. | ||
let mut gen_move = |mut x: Box<usize>| { | ||
loop { | ||
drop(x); | ||
x = yield; | ||
} | ||
}; | ||
|
||
assert_eq!(Pin::new(&mut gen_copy).resume(0), GeneratorState::Yielded(())); | ||
assert_eq!(Pin::new(&mut gen_copy).resume(1), GeneratorState::Yielded(())); | ||
|
||
assert_eq!(Pin::new(&mut gen_move).resume(Box::new(0)), GeneratorState::Yielded(())); | ||
assert_eq!(Pin::new(&mut gen_move).resume(Box::new(1)), GeneratorState::Yielded(())); | ||
} |
136 changes: 136 additions & 0 deletions
136
tests/kani/Generator/rustc-generator-tests/size-moved-locals-slow_fixme.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// | ||
// Modifications Copyright Kani Contributors | ||
// See GitHub history for details. | ||
|
||
// Copyright rustc Contributors | ||
// Adapted from rustc: https://github.com/rust-lang/rust/tree/5f98537eb7b5f42c246a52c550813c3cff336069/src/test/ui/generator/size-moved-locals.rs | ||
|
||
// run-pass | ||
// Test that we don't duplicate storage for a variable that is moved to another | ||
// binding. This used to happen in the presence of unwind and drop edges (see | ||
// `complex` below.) | ||
// | ||
// The exact sizes here can change (we'd like to know when they do). What we | ||
// don't want to see is the `complex` generator size being upwards of 2048 bytes | ||
// (which would indicate it is reserving space for two copies of Foo.) | ||
// | ||
// See issue #59123 for a full explanation. | ||
|
||
// edition:2018 | ||
// ignore-wasm32 issue #62807 | ||
// ignore-asmjs issue #62807 | ||
|
||
#![feature(generators, generator_trait)] | ||
|
||
use std::ops::{Generator, GeneratorState}; | ||
use std::pin::Pin; | ||
|
||
const FOO_SIZE: usize = 1024; | ||
struct Foo([u8; FOO_SIZE]); | ||
|
||
impl Drop for Foo { | ||
fn drop(&mut self) {} | ||
} | ||
|
||
fn move_before_yield() -> impl Generator<Yield = (), Return = ()> { | ||
static || { | ||
let first = Foo([0; FOO_SIZE]); | ||
let _second = first; | ||
yield; | ||
// _second dropped here | ||
} | ||
} | ||
|
||
fn noop() {} | ||
|
||
fn move_before_yield_with_noop() -> impl Generator<Yield = (), Return = ()> { | ||
static || { | ||
let first = Foo([0; FOO_SIZE]); | ||
noop(); | ||
let _second = first; | ||
yield; | ||
// _second dropped here | ||
} | ||
} | ||
|
||
// Today we don't have NRVO (we allocate space for both `first` and `second`,) | ||
// but we can overlap `first` with `_third`. | ||
fn overlap_move_points() -> impl Generator<Yield = (), Return = ()> { | ||
static || { | ||
let first = Foo([0; FOO_SIZE]); | ||
yield; | ||
let second = first; | ||
yield; | ||
let _third = second; | ||
yield; | ||
} | ||
} | ||
|
||
fn overlap_x_and_y() -> impl Generator<Yield = (), Return = ()> { | ||
static || { | ||
let x = Foo([0; FOO_SIZE]); | ||
yield; | ||
drop(x); | ||
let y = Foo([0; FOO_SIZE]); | ||
yield; | ||
drop(y); | ||
} | ||
} | ||
|
||
#[kani::proof] | ||
fn main() { | ||
// FIXME: the following tests are very slow (did not terminate in a couple of minutes) | ||
/* let mut generator = move_before_yield(); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Complete(()) | ||
); | ||
|
||
let mut generator = move_before_yield_with_noop(); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Complete(()) | ||
); | ||
|
||
let mut generator = overlap_move_points(); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Complete(()) | ||
); | ||
|
||
let mut generator = overlap_x_and_y(); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Yielded(()) | ||
); | ||
assert_eq!( | ||
unsafe { Pin::new_unchecked(&mut generator) }.resume(()), | ||
GeneratorState::Complete(()) | ||
); */ | ||
assert!(false); // to make the test fail without taking forever | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please create an issue to take a look at the performance of this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #1406