Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions compiler/rustc_builtin_macros/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@ fn expand_contract_clause_tts(
annotated: TokenStream,
clause_keyword: rustc_span::Symbol,
) -> Result<TokenStream, ErrorGuaranteed> {
if annotation.is_empty() {
let (name, example) = if clause_keyword == kw::ContractRequires {
("requires", "condition")
} else {
("ensures", "|result: &T| condition")
};
ecx.sess.dcx().span_err(
attr_span,
format!("`{name}` attribute requires an argument, e.g., `#[{name}({example})]`"),
);
// Returning `Err` would replace it with a dummy fragment and cause cascading name-resolution errors.
// Instead, we return the original token stream so that there is no later noises.
return Ok(annotated);
}

let feature_span = ecx.with_def_site_ctxt(attr_span);
expand_contract_clause(ecx, attr_span, annotated, |new_tts| {
new_tts.push(TokenTree::Token(
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/contracts/empty-ensures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate core;
use core::contracts::ensures;

#[ensures()]
//~^ ERROR expected an `Fn(&_)` closure, found `()` [E0277]
//~^ ERROR `ensures` attribute requires an argument
fn foo(x: u32) -> u32 {
x * 2
}
Expand Down
10 changes: 1 addition & 9 deletions tests/ui/contracts/empty-ensures.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
error[E0277]: expected an `Fn(&_)` closure, found `()`
error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]`
--> $DIR/empty-ensures.rs:8:1
|
LL | #[ensures()]
| ^^^^^^^^^^^^
| |
| expected an `Fn(&_)` closure, found `()`
| required by a bound introduced by this call
|
= help: the trait `for<'a> Fn(&'a _)` is not implemented for `()`
note: required by a bound in `build_check_ensures`
--> $SRC_DIR/core/src/contracts.rs:LL:COL

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
4 changes: 1 addition & 3 deletions tests/ui/contracts/empty-requires.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@ dont-require-annotations: NOTE
//@ compile-flags: -Zcontract-checks=yes
#![expect(incomplete_features)]
#![feature(contracts)]
Expand All @@ -7,8 +6,7 @@ extern crate core;
use core::contracts::requires;

#[requires()]
//~^ ERROR mismatched types [E0308]
//~| NOTE expected `bool`, found `()`
//~^ ERROR `requires` attribute requires an argument
fn foo(x: u32) -> u32 {
x * 2
}
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/contracts/empty-requires.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
error[E0308]: mismatched types
--> $DIR/empty-requires.rs:9:1
error: `requires` attribute requires an argument, e.g., `#[requires(condition)]`
--> $DIR/empty-requires.rs:8:1
|
LL | #[requires()]
| ^^^^^^^^^^^^^ expected `bool`, found `()`
| ^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
18 changes: 18 additions & 0 deletions tests/ui/lint/single-use-lifetimes-issue-146834.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Regression test for https://github.com/rust-lang/rust/issues/146834.

//@ compile-flags: -Wsingle-use-lifetimes
//@ edition: 2024

#![expect(incomplete_features)]
#![feature(contracts)]

#[core::contracts::ensures]
//~^ ERROR `ensures` attribute requires an argument
fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
//~^ ERROR missing lifetime specifiers
//~| WARN lifetime parameter `'a` only used once
//~| WARN lifetime parameter `'b` only used once
loop {}
}

fn main() {}
55 changes: 55 additions & 0 deletions tests/ui/lint/single-use-lifetimes-issue-146834.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]`
--> $DIR/single-use-lifetimes-issue-146834.rs:9:1
|
LL | #[core::contracts::ensures]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0106]: missing lifetime specifiers
--> $DIR/single-use-lifetimes-issue-146834.rs:11:42
|
LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
| ------- ------- ^ ^ expected named lifetime parameter
| |
| expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
note: these named lifetimes are available to use
--> $DIR/single-use-lifetimes-issue-146834.rs:11:6
|
LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
| ^^ ^^
help: consider using one of the available lifetimes here
|
LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&'lifetime i32, &'lifetime i32) {
| +++++++++ +++++++++

warning: lifetime parameter `'a` only used once
--> $DIR/single-use-lifetimes-issue-146834.rs:11:6
|
LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
| ^^ -- ...is used only here
| |
| this lifetime...
|
= note: requested on the command line with `-W single-use-lifetimes`
help: elide the single-use lifetime
|
LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
LL + fn f<'b>(a: &i32, b: &'b i32) -> (&i32, &i32) {
|

warning: lifetime parameter `'b` only used once
--> $DIR/single-use-lifetimes-issue-146834.rs:11:10
|
LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
| ^^ this lifetime... -- ...is used only here
|
help: elide the single-use lifetime
|
LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) {
LL + fn f<'a>(a: &'a i32, b: &i32) -> (&i32, &i32) {
|

error: aborting due to 2 previous errors; 2 warnings emitted

For more information about this error, try `rustc --explain E0106`.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
struct T;

impl T {
#[core::contracts::ensures] //~ ERROR expected an `Fn(&_)` closure, found `()`
#[core::contracts::ensures] //~ ERROR `ensures` attribute requires an argument
fn b() {(loop)}
//~^ ERROR expected `{`, found `)`
//~| ERROR expected `{`, found `)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ LL | fn b() {(loop)}
| |
| while parsing this `loop` expression

error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5
|
LL | #[core::contracts::ensures]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: expected `{`, found `)`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18
|
Expand All @@ -16,19 +22,5 @@ LL | fn b() {(loop)}
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0277]: expected an `Fn(&_)` closure, found `()`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5
|
LL | #[core::contracts::ensures]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected an `Fn(&_)` closure, found `()`
| required by a bound introduced by this call
|
= help: the trait `for<'a> Fn(&'a _)` is not implemented for `()`
note: required by a bound in `build_check_ensures`
--> $SRC_DIR/core/src/contracts.rs:LL:COL

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Loading