diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 56413160e04de..6cffd8e119b7e 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -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_hir::Stmt<'hir> { let lowered_req = self.lower_expr_mut(&req); diff --git a/tests/ui/contracts/requires-block-stmt.rs b/tests/ui/contracts/requires-block-stmt.rs new file mode 100644 index 0000000000000..0f0801bb65f5b --- /dev/null +++ b/tests/ui/contracts/requires-block-stmt.rs @@ -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() +}