Abstract
Closures are a language feature supported by many mainstream languages, combining the ability to package up references to code blocks with the possibility of capturing state from the environment of the closure's declaration. Closures are powerful, but complicate understanding and formal reasoning, especially when closure invocations may mutate objects reachable from the captured state or from closure arguments.
This paper presents a novel technique for the modular specification and verification of closure-manipulating code in Rust. Our technique combines Rust's type system guarantees and novel specification features to enable formal verification of rich functional properties. It encodes higher-order concerns into a first-order logic, which enables automation via SMT solvers. Our technique is implemented as an extension of the deductive verifier Prusti, with which we have successfully verified many common idioms of closure usage.
Supplemental Material
- Vytautas Astrauskas, Christoph Matheja, Federico Poli, Peter Müller, and Alexander J. Summers. 2020. How do programmers use unsafe Rust? Proc. ACM Program. Lang., 4, OOPSLA (2020), Article 136, 11, 27 pages. https://doi.org/10.1145/3428204 Google Scholar
Digital Library
- Vytautas Astrauskas, Peter Müller, Federico Poli, and Alexander J. Summers. 2019. Leveraging Rust types for modular specification and verification. Proc. ACM Program. Lang., 3, OOPSLA (2019), Article 147, Oct., 30 pages. https://doi.org/10.1145/3360573 Google Scholar
Digital Library
- Mike Barnett, Bor-Yuh Evan Chang, Robert DeLine, Bart Jacobs, and K. Rustan M. Leino. 2006. Boogie: A Modular Reusable Verifier for Object-Oriented Programs. In Formal Methods for Components and Objects, Frank S. de Boer, Marcello M. Bonsangue, Susanne Graf, and Willem-Paul de Roever (Eds.) (LNCS, Vol. 4111). Springer, Berlin, Heidelberg. 364–387. https://doi.org/10.1007/11804192_17 Google Scholar
Digital Library
- Arthur Charguéraud and François Pottier. 2008. Functional translation of a calculus of capabilities. In ICFP. Association for Computing Machinery, New York, NY, USA. 213–224. https://doi.org/10.1145/1411204.1411235 Google Scholar
Digital Library
- Ernie Cohen, Mark A. Hillebrand, Stephan Tobies, Michał Moskal, and Wolfram Schulte. 2015. Verifying C Programs: A VCC Tutorial. https://bit.ly/32BkCWN Working draft, version 0.2.Google Scholar
- Ádám Darvas and K. Rustan M. Leino. 2007. Practical Reasoning About Invocations and Implementations of Pure Methods. In Fundamental Approaches to Software Engineering, Matthew B. Dwyer and Antónia Lopes (Eds.) (LNCS, Vol. 4422). Springer, Berlin, Heidelberg. 336–351. https://doi.org/10.1007/978-3-540-71289-3_26 Google Scholar
Cross Ref
- Leonardo Mendonça de Moura and Nikolaj Bjørner. 2007. Efficient E-Matching for SMT Solvers. In Automated Deduction – CADE-21, Frank Pfenning (Ed.). 4603, Springer, 183–198. https://doi.org/10.1007/978-3-540-73595-3_13 Google Scholar
Digital Library
- Krishna K. Dhara and Gary T. Leavens. 1996. Forcing behavioral subtyping through specification inheritance. In Proceedings of IEEE 18th International Conference on Software Engineering. IEEE Computer Society Press, Los Alamitos, CA, USA. 258–267. https://doi.org/10.1109/ICSE.1996.493421 Google Scholar
Cross Ref
- Ana Nora Evans, Bradford Campbell, and Mary Lou Soffa. 2020. Is Rust Used Safely by Software Developers? In Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering (ICSE ’20). Association for Computing Machinery, New York, NY, USA. 246–257. https://doi.org/10.1145/3377811.3380413 Google Scholar
Digital Library
- Robert Bruce Findler and Matthias Felleisen. 2002. Contracts for higher-order functions. In ICFP. ACM, New York, NY, USA. 48–59. https://doi.org/10.1145/581478.581484 Google Scholar
Digital Library
- David Harel, Dexter Kozen, and Jerzy Tiuryn. 2002. Dynamic Logic. In Handbook of Philosophical Logic, Dov M. Gabbay and Franz Guenthner (Eds.) (Handbook of Philosophical Logic, Vol. 4). Springer Netherlands, Dordrecht. 99–217. https://doi.org/10.1007/978-94-017-0456-4_2 Google Scholar
Cross Ref
- Kohei Honda, Nobuko Yoshida, and Martin Berger. 2005. An Observationally Complete Program Logic for Imperative Higher-Order Frame Rules. In 20th Annual IEEE Symposium on Logic in Computer Science (LICS ’05). IEEE Computer Society, Los Alamitos, CA, USA. 270–279. https://doi.org/10.1109/LICS.2005.5 Google Scholar
Digital Library
- Bart Jacobs, Jan Smans, Pieter Philippaerts, Frédéric Vogels, Willem Penninckx, and Frank Piessens. 2011. VeriFast: A Powerful, Sound, Predictable, Fast Verifier for C and Java. In NFM 2011, Mihaela Gheorghiu Bobaru, Klaus Havelund, Gerard J. Holzmann, and Rajeev Joshi (Eds.) (LNCS, Vol. 6617). Springer, 41–55. https://doi.org/10.1007/978-3-642-20398-5_4 Google Scholar
Cross Ref
- Johannes Kanig and Jean-Christophe Filliâtre. 2009. Who: a verifier for effectful higher-order programs. In Proceedings of the 2009 ACM SIGPLAN workshop on ML (ML ’09). Association for Computing Machinery, New York, NY, USA. 39–48. https://doi.org/10.1145/1596627.1596634 Google Scholar
Digital Library
- Ioannis T. Kassios. 2006. Dynamic Frames: Support for Framing, Dependencies and Sharing Without Restrictions. In FM 2006: Formal Methods, Jayadev Misra, Tobias Nipkow, and Emil Sekerinski (Eds.). Springer, Berlin, Heidelberg. 268–283. https://doi.org/10.1007/11813040_19 Google Scholar
Digital Library
- Ioannis T. Kassios and Peter Müller. 2010. Specification and verification of closures. ETH Zürich. https://doi.org/10.3929/ETHZ-A-006843251 Google Scholar
Cross Ref
- Steve Klabnik and Carol Nichols. 2021. The Rust Programming Language. https://doc.rust-lang.org/book/Google Scholar
- Neelakantan R. Krishnaswami. 2012. Verifying Higher-Order Imperative Programs with Higher-Order Separation Logic. Ph.D. Dissertation. Carnegie Mellon University. https://doi.org/10.1184/R1/6724235.v1 Google Scholar
Cross Ref
- Peter J. Landin. 1964. The Mechanical Evaluation of Expressions. Comput. J., 6, 4 (1964), 1 Jan., 308–320. https://doi.org/10.1093/comjnl/6.4.308 Google Scholar
Cross Ref
- Gary T. Leavens and David A. Naumann. 2015. Behavioral Subtyping, Specification Inheritance, and Modular Reasoning. ACM Trans. Program. Lang. Syst., 37, 4 (2015), Article 13, Aug., 88 pages. https://doi.org/10.1145/2766446 Google Scholar
Digital Library
- Gary T Leavens, Erik Poll, Curtis Clifton, Yoonsik Cheon, Clyde Ruby, David Cok, Peter Müller, Joseph Kiniry, Patrice Chalin, and Daniel M Zimmerman. 2008. JML reference manual.Google Scholar
- K. Rustan M. Leino. 2010. Dafny: An Automatic Program Verifier for Functional Correctness. In Logic for Programming, Artificial Intelligence, and Reasoning, Edmund M. Clarke and Andrei Voronkov (Eds.) (LNCS, Vol. 6355). Springer, Berlin, Heidelberg. 348–370. https://doi.org/10.1007/978-3-642-17511-4_20 Google Scholar
Cross Ref
- Barbara H. Liskov and Jeannette M. Wing. 1994. A behavioral notion of subtyping. ACM Trans. Program. Lang. Syst., 16, 6 (1994), Nov., 1811–1841. https://doi.org/10.1145/197320.197383 Google Scholar
Digital Library
- Nicholas D. Matsakis. 2013. The Case of the Recurring Closure. http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closureGoogle Scholar
- Nicholas D. Matsakis and Felix S. Klock. 2014. The Rust language. Ada Lett., 34, 3 (2014), Oct., 103–104. https://doi.org/10.1145/2692956.2663188 Google Scholar
Digital Library
- Davood Mazinanian, Ameya Ketkar, Nikolaos Tsantalis, and Danny Dig. 2017. Understanding the use of lambda expressions in Java. Proc. ACM Program. Lang., 1, OOPSLA (2017), Article 85, Oct., 31 pages. https://doi.org/10.1145/3133909 Google Scholar
Digital Library
- Peter Müller, Malte Schwerhoff, and Alexander J. Summers. 2016. Viper: A Verification Infrastructure for Permission-Based Reasoning. In Verification, Model Checking, and Abstract Interpretation, Barbara Jobstmann and K. Rustan M. Leino (Eds.) (LNCS, Vol. 9583). Springer, Berlin, Heidelberg. 41–62. https://doi.org/10.1007/978-3-662-49122-5_2 Google Scholar
Digital Library
- Aleksandar Nanevski, Greg Morrisett, and Lars Birkedal. 2008. Hoare type theory, polymorphism and separation. J. Funct. Prog., 18, 5–6 (2008), Sept., 865–911. https://doi.org/10.1017/S0956796808006953 Google Scholar
Digital Library
- Aleksandar Nanevski, Greg Morrisett, Avraham Shinnar, Paul Govereau, and Lars Birkedal. 2008. Ynot: dependent types for imperative programs. In ICFP. Association for Computing Machinery, New York, NY, USA. 229–240. https://doi.org/10.1145/1411204.1411237 Google Scholar
Digital Library
- Martin Nordio, Cristiano Calcagno, Bertrand Meyer, Peter Müller, and Julian Tschannen. 2010. Reasoning about Function Objects. In Objects, Models, Components, Patterns, Jan Vitek (Ed.) (LNCS, Vol. 6141). Springer, Berlin, Heidelberg. 79–96. https://doi.org/10.1007/978-3-642-13953-6_5 Google Scholar
Cross Ref
- Peter O’Hearn, John Reynolds, and Hongseok Yang. 2001. Local Reasoning about Programs that Alter Data Structures. In Computer Science Logic, Laurent Fribourg (Ed.) (LNCS, Vol. 2142). Springer, Berlin, Heidelberg. 1–19. https://doi.org/10.1007/3-540-44802-0_1 Google Scholar
Cross Ref
- Peter W. O’Hearn and John C. Reynolds. 2000. From Algol to polymorphic linear lambda-calculus. J. ACM, 47, 1 (2000), Jan., 167–223. https://doi.org/10.1145/331605.331611 Google Scholar
Digital Library
- Mário José Parreira Pereira. 2018. Tools and Techniques for the Verification of Modular Stateful Code. Ph.D. Dissertation. Université Paris Saclay. https://tel.archives-ouvertes.fr/tel-01980343/documentGoogle Scholar
- Yann Régis-Gianas and François Pottier. 2008. A Hoare Logic for Call-by-Value Functional Programs. In Mathematics of Program Construction, Philippe Audebaud and Christine Paulin-Mohring (Eds.) (LNCS, Vol. 5133). Springer, Berlin, Heidelberg. 305–335. https://doi.org/10.1007/978-3-540-70594-9_17 Google Scholar
Digital Library
- Steve M. Shaner, Gary T. Leavens, and David A. Naumann. 2007. Modular verification of higher-order methods with mandatory calls specified by model programs. In OOPSLA. Association for Computing Machinery, New York, NY, USA. 351–368. https://doi.org/10.1145/1297027.1297053 Google Scholar
Digital Library
- Jan Smans, Bart Jacobs, and Frank Piessens. 2010. Heap-Dependent Expressions in Separation Logic. In Formal Techniques for Distributed Systems, John Hatcliff and Elena Zucca (Eds.) (LNCS, Vol. 6117). Springer, Berlin, Heidelberg. 170–185. https://doi.org/10.1007/978-3-642-13464-7_14 Google Scholar
Digital Library
- Jan Smans, Bart Jacobs, and Frank Piessens. 2012. Implicit Dynamic Frames. ACM Trans. Program. Lang. Syst., 34, 1 (2012), Article 2, May, 58 pages. https://doi.org/10.1145/2160910.2160911 Google Scholar
Digital Library
- Neelam Soundarajan and Stephen Fridella. 2004. Incremental Reasoning for Object Oriented Systems. In From Object-Orientation to Formal Methods, Olaf Owe, Stein Krogdahl, and Tom Lyche (Eds.) (LNCS, Vol. 2635). Springer, Berlin, Heidelberg. 302–333. https://doi.org/10.1007/978-3-540-39993-3_15 Google Scholar
Cross Ref
- Kasper Svendsen, Lars Birkedal, and Matthew Parkinson. 2010. Verifying Generics and Delegates. In ECOOP 2010 – Object-Oriented Programming, Theo D’Hondt (Ed.) (LNCS, Vol. 6183). Springer, Berlin, Heidelberg. 175–199. https://doi.org/10.1007/978-3-642-14107-2_9 Google Scholar
Cross Ref
- Nikhil Swamy, Joel Weinberger, Cole Schlesinger, Juan Chen, and Benjamin Livshits. 2013. Verifying higher-order programs with the Dijkstra monad. SIGPLAN Not., 48, 6 (2013), June, 387–398. https://doi.org/10.1145/2499370.2491978 Google Scholar
Digital Library
- Fabian Wolff. 2020. Verification of Closures in Rust Programs. Master’s thesis. ETH Zürich. https://doi.org/10.3929/ethz-b-000444764 Google Scholar
Cross Ref
- Fabian Wolff, Aurel Bílý, Christoph Matheja, Peter Müller, and Alexander J. Summers. 2021. Modular Specification and Verification of Closures in Rust (artefact). https://doi.org/10.5281/zenodo.5482557 Google Scholar
Digital Library
- Fabian Wolff, Aurel Bílý, Christoph Matheja, Peter Müller, and Alexander J. Summers. 2021. Prusti extension for closure verification. https://github.com/Aurel300/prusti-dev/tree/closure-oopsla-submission-2Google Scholar
- Nobuko Yoshida, Kohei Honda, and Martin Berger. 2007. Logical Reasoning for Higher-Order Functions with Local State. In Foundations of Software Science and Computational Structures, Helmut Seidl (Ed.) (LNCS, Vol. 4423). Springer, Berlin, Heidelberg. 361–377. https://doi.org/10.1007/978-3-540-71389-0_26 Google Scholar
Cross Ref
Index Terms
Modular specification and verification of closures in Rust
Recommendations
Leveraging rust types for modular specification and verification
Rust's type system ensures memory safety: well-typed Rust programs are guaranteed to not exhibit problems such as dangling pointers, data races, and unexpected side effects through aliased references. Ensuring correctness properties beyond memory safety,...
Capsules and Closures
Capsules are a clean representation of the state of a computation in higher-order programming languages with effects. Their intent is to simplify and replace the notion of closure. They naturally provide support for functional and imperative features, ...
Efficient Verification of Sequential and Concurrent C Programs
There has been considerable progress in the domain of software verification over the last few years. This advancement has been driven, to a large extent, by the emergence of powerful yet automated abstraction techniques such as predicate abstraction. ...






Comments