contracts: fix lowering final declaration without trailing semicolon
Lowering for contract delcarations incorrectly handled the final declaration statement when it didn't end in a semicolon. This change fixes the issue.
This commit is contained in:
parent
da2544bfbe
commit
d54fee82f4
2 changed files with 35 additions and 1 deletions
|
|
@ -23,7 +23,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// The order in which things are lowered is important! I.e to
|
||||
// refer to variables in contract_decls from postcond/precond,
|
||||
// we must lower it first!
|
||||
let contract_decls = self.lower_stmts(&contract.declarations).0;
|
||||
let contract_decls = self.lower_decls(contract);
|
||||
|
||||
match (&contract.requires, &contract.ensures) {
|
||||
(Some(req), Some(ens)) => {
|
||||
|
|
@ -124,6 +124,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_decls(&mut self, contract: &rustc_ast::FnContract) -> &'hir [rustc_hir::Stmt<'hir>] {
|
||||
let (decls, decls_tail) = self.lower_stmts(&contract.declarations);
|
||||
|
||||
if let Some(e) = decls_tail {
|
||||
// include the tail expression in the declaration statements
|
||||
let tail = self.stmt_expr(e.span, *e);
|
||||
self.arena.alloc_from_iter(decls.into_iter().map(|d| *d).chain([tail].into_iter()))
|
||||
} else {
|
||||
decls
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower the precondition check intrinsic.
|
||||
fn lower_precond(&mut self, req: &Box<rustc_ast::Expr>) -> rustc_hir::Stmt<'hir> {
|
||||
let lowered_req = self.lower_expr_mut(&req);
|
||||
|
|
|
|||
22
tests/ui/contracts/requires-block-stmt.rs
Normal file
22
tests/ui/contracts/requires-block-stmt.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//@ run-pass
|
||||
//@ compile-flags: -Zcontract-checks=yes
|
||||
|
||||
#![expect(incomplete_features)]
|
||||
#![feature(contracts)]
|
||||
extern crate core;
|
||||
use core::contracts::requires;
|
||||
|
||||
// Compound statements (those using [ExpressionWithBlock]
|
||||
// (https://doc.rust-lang.org/beta/reference/expressions.html#railroad-ExpressionWithBlock))
|
||||
// like blocks, if-expressions, and loops require no trailing semicolon. This
|
||||
// regression test captures the case where the last statement in the contract
|
||||
// declarations has no trailing semicolon.
|
||||
#[requires(
|
||||
{}
|
||||
true
|
||||
)]
|
||||
fn foo() {}
|
||||
|
||||
fn main() {
|
||||
foo()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue