Auto merge of #141295 - Kivooeo:if-let-guard-stable, r=fee1-dead,est31

Stabilize `if let` guards (`feature(if_let_guard)`)



## Summary

This proposes the stabilization of `if let` guards (tracking issue: rust-lang/rust#51114, RFC: rust-lang/rfcs#2294). This feature allows `if let` expressions to be used directly within match arm guards, enabling conditional pattern matching within guard clauses.

## What is being stabilized

The ability to use `if let` expressions within match arm guards.

Example:

```rust
enum Command {
    Run(String),
    Stop,
    Pause,
}

fn process_command(cmd: Command, state: &mut String) {
    match cmd {
        Command::Run(name) if let Some(first_char) = name.chars().next() && first_char.is_ascii_alphabetic() => {
            // Both `name` and `first_char` are available here
            println!("Running command: {} (starts with '{}')", name, first_char);
            state.push_str(&format!("Running {}", name));
        }
        Command::Run(name) => {
            println!("Cannot run command '{}'. Invalid name.", name);
        }
        Command::Stop if state.contains("running") => {
            println!("Stopping current process.");
            state.clear();
        }
        _ => {
            println!("Unhandled command or state.");
        }
    }
}
```

## Motivation

The primary motivation for `if let` guards is to reduce nesting and improve readability when conditional logic depends on pattern matching. Without this feature, such logic requires nested `if let` statements within match arms:

```rust
// Without if let guards
match value {
    Some(x) => {
        if let Ok(y) = compute(x) {
            // Both `x` and `y` are available here
            println!("{}, {}", x, y);
        }
    }
    _ => {}
}

// With if let guards
match value {
    Some(x) if let Ok(y) = compute(x) => {
        // Both `x` and `y` are available here
        println!("{}, {}", x, y);
    }
    _ => {}
}
```

## Implementation and Testing

The feature has been implemented and tested comprehensively across different scenarios:

### Core Functionality Tests

**Scoping and variable binding:**
- [`scope.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs) - Verifies that bindings created in `if let` guards are properly scoped and available in match arms
- [`shadowing.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs) - Tests that variable shadowing works correctly within guards
- [`scoping-consistency.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/scoping-consistency.rs) - Ensures temporaries in guards remain valid for the duration of their match arms

**Type system integration:**
- [`type-inference.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs) - Confirms type inference works correctly in `if let` guards  
- [`typeck.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/typeck.rs) - Verifies type mismatches are caught appropriately

**Pattern matching semantics:**
- [`exhaustive.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs) - Validates that `if let` guards are correctly handled in exhaustiveness analysis
- [`move-guard-if-let.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs) and [`move-guard-if-let-chain.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs) - Test that conditional moves in guards are tracked correctly by the borrow checker

### Error Handling and Diagnostics

- [`warns.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs) - Tests warnings for irrefutable patterns and unreachable code in guards
- [`parens.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs) - Ensures parentheses around `let` expressions are properly rejected
- [`macro-expanded.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs) - Verifies macro expansions that produce invalid constructs are caught
- [`guard-mutability-2.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs) - Tests mutability and ownership violations in guards
- [`ast-validate-guards.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs) - Validates AST-level syntax restrictions

### Drop Order and Temporaries

**Key insight:** Unlike `let_chains` in regular `if` expressions, `if let` guards do not have drop order inconsistencies because:
1. Match guards are clearly scoped to their arms
2. There is no "else block" equivalent that could cause temporal confusion

- [`drop-order.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/drop-order.rs) - Check drop order of temporaries create in match guards
- [`compare-drop-order.rs`](https://github.com/rust-lang/rust/blob/aef3f5fdf052fbbc16e174aef5da6d50832ca316/tests/ui/rfcs/rfc-2294-if-let-guard/compare-drop-order.rs) - Compares drop order between `if let` guards and nested `if let` in match arms, confirming they behave identically across all editions
- rust-lang/rust#140981 - A complicated drop order test involved `let chain` was made by @est31
- [`drop-order-comparisons-let-chains.rs`](https://github.com/rust-lang/rust/blob/902b4d28783e03e231d8513082cc30c4fcce5d95/tests/ui/drop/drop-order-comparisons-let-chains.rs) - Compares drop order between `let chains` in `if let guard` and regular `if` expressions
- [`if-let-guards.rs`](https://github.com/rust-lang/rust/blob/5650d716e0589e2e145ce9027f35bd534e5f862a/tests/ui/drop/if-let-guards.rs) - Test correctness of drop order for bindings and temporaries
- [`if-let-guards-2`](https://github.com/rust-lang/rust/blob/3a6c8c8f3d7ae654fdb6ce1255182bda21680655/tests/ui/drop/if-let-guards-2.rs) - The same test as above but more comprehensive and tests more interactions between different features and their drop order, checking that drop order is correct, created by @traviscross 

## Edition Compatibility

This feature stabilizes on all editions, unlike `let chains` which was limited to edition 2024. This is safe because:

1. `if let` guards don't suffer from the drop order issues that affected `let chains` in regular `if` expressions
2. The scoping is unambiguous - guards are clearly tied to their match arms
3. Extensive testing confirms identical behavior across all editions

## Interactions with Future Features

The lang team has reviewed potential interactions with planned "guard patterns" and determined that stabilizing `if let` guards now does not create obstacles for future work. The scoping and evaluation semantics established here align with what guard patterns will need.

## Unresolved Issues

- [x] - rust-lang/rust#140981
- [x] - added tests description by @jieyouxu request
- [x] - Concers from @scottmcm about stabilizing this across all editions
- [x] - check if drop order in all edition when using `let chains` inside `if let` guard is the same
- [x] - interactions with guard patters
- [x] - pattern bindings drops before guard bindings https://github.com/rust-lang/rust/pull/143376
- [x] - documentaion (https://github.com/rust-lang/reference/pull/1957)
- [ ] (non-blocking) add tests for [this](https://github.com/rust-lang/rust/issues/145237) and [this](https://github.com/rust-lang/rust/pull/141295#issuecomment-3173059821)

---

**Related:**
- Tracking Issue: rust-lang/rust#51114  
- RFC: rust-lang/rfcs#2294
- Documentation PR: https://github.com/rust-lang/reference/pull/1957
This commit is contained in:
bors
2026-02-18 20:49:50 +00:00
148 changed files with 746 additions and 731 deletions
+1 -1
View File
@@ -5,10 +5,10 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![doc(test(attr(deny(warnings), allow(internal_features))))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(macro_metavar_expr)]
#![recursion_limit = "256"]
+1 -1
View File
@@ -31,8 +31,8 @@
//! in the HIR, especially for multiple identifiers.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
// tidy-alphabetical-end
use std::mem;
@@ -481,11 +481,6 @@ macro_rules! gate_all {
}
};
}
gate_all!(
if_let_guard,
"`if let` guards are experimental",
"you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
);
gate_all!(
async_trait_bounds,
"`async` trait bounds are unstable",
+1 -1
View File
@@ -3,8 +3,8 @@
//! by `rustc_ast_lowering`.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_is_partitioned)]
// tidy-alphabetical-end
+1 -1
View File
@@ -77,8 +77,8 @@
//! containing both `C` and `packed` annotations.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
// tidy-alphabetical-end
+1 -1
View File
@@ -3,10 +3,10 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(default_field_values)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]
+1 -1
View File
@@ -4,9 +4,9 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
+1 -1
View File
@@ -6,9 +6,9 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(extern_types)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(macro_derive)]
+1 -1
View File
@@ -1,8 +1,8 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(string_from_utf8_lossy_owned)]
#![feature(trait_alias)]
+1 -1
View File
@@ -1,9 +1,9 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(array_try_map)]
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(never_type)]
#![feature(slice_ptr_get)]
#![feature(trait_alias)]
+1 -1
View File
@@ -1,7 +1,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
+2
View File
@@ -240,6 +240,8 @@ macro_rules! declare_features {
(accepted, i128_type, "1.26.0", Some(35118)),
/// Allows the use of `if let` expressions.
(accepted, if_let, "1.0.0", None),
/// Allows `if let` guard in match arms.
(accepted, if_let_guard, "CURRENT_RUSTC_VERSION", Some(51114)),
/// Rescoping temporaries in `if let` to align with Rust 2024.
(accepted, if_let_rescope, "1.84.0", Some(124085)),
/// Allows top level or-patterns (`p | q`) in `if let` and `while let`.
-2
View File
@@ -518,8 +518,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
(unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)),
/// Target features on hexagon.
(unstable, hexagon_target_feature, "1.27.0", Some(150250)),
/// Allows `if let` guard in match arms.
(unstable, if_let_guard, "1.47.0", Some(51114)),
/// Allows `impl Trait` to be used inside associated types (RFC 2515).
(unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
/// Allows `impl Trait` in bindings (`let`).
+1 -1
View File
@@ -57,9 +57,9 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(default_field_values)]
#![feature(gen_blocks)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(never_type)]
#![feature(slice_partition_dedup)]
+1 -1
View File
@@ -1,7 +1,7 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
#![feature(never_type)]
+1 -1
View File
@@ -22,8 +22,8 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(rustc_attrs)]
#![feature(try_blocks)]
+1 -1
View File
@@ -1,9 +1,9 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(error_iter)]
#![feature(file_buffered)]
#![feature(gen_blocks)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(min_specialization)]
#![feature(never_type)]
+1 -1
View File
@@ -28,6 +28,7 @@
#![allow(internal_features)]
#![allow(rustc::direct_use_of_rustc_type_ir)]
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![cfg_attr(doc, feature(intra_doc_pointers))]
#![feature(allocator_api)]
#![feature(associated_type_defaults)]
@@ -43,7 +44,6 @@
#![feature(extern_types)]
#![feature(file_buffered)]
#![feature(gen_blocks)]
#![feature(if_let_guard)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
+1 -1
View File
@@ -2,8 +2,8 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(try_blocks)]
// tidy-alphabetical-end
+1 -1
View File
@@ -1,10 +1,10 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(const_type_name)]
#![feature(cow_is_borrowed)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
+1 -1
View File
@@ -1,6 +1,6 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(once_cell_get_mut)]
// tidy-alphabetical-end
+1 -1
View File
@@ -2,11 +2,11 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![cfg_attr(test, feature(iter_order_by))]
#![feature(box_patterns)]
#![feature(debug_closure_helpers)]
#![feature(default_field_values)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
// tidy-alphabetical-end
+2 -26
View File
@@ -3459,40 +3459,16 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
}
fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<Box<Expr>>> {
// Used to check the `if_let_guard` feature mostly by scanning
// `&&` tokens.
fn has_let_expr(expr: &Expr) -> bool {
match &expr.kind {
ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, lhs, rhs) => {
let lhs_rslt = has_let_expr(lhs);
let rhs_rslt = has_let_expr(rhs);
lhs_rslt || rhs_rslt
}
ExprKind::Let(..) => true,
_ => false,
}
}
if !self.eat_keyword(exp!(If)) {
// No match arm guard present.
return Ok(None);
}
let if_span = self.prev_token.span;
let mut cond = self.parse_match_guard_condition()?;
let mut checker = CondChecker::new(self, LetChainsPolicy::AlwaysAllowed);
checker.visit_expr(&mut cond);
CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
if has_let_expr(&cond) {
let span = if_span.to(cond.span);
self.psess.gated_spans.gate(sym::if_let_guard, span);
}
Ok(Some(if let Some(guar) = checker.found_incorrect_let_chain {
self.mk_expr_err(cond.span, guar)
} else {
cond
}))
Ok(Some(cond))
}
fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option<Box<Expr>>)> {
+1 -1
View File
@@ -9,6 +9,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![cfg_attr(bootstrap, feature(ptr_as_ref_unchecked))]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
@@ -16,7 +17,6 @@
#![feature(const_trait_impl)]
#![feature(control_flow_into_value)]
#![feature(default_field_values)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(rustc_attrs)]
#![feature(trim_prefix_suffix)]
+1 -1
View File
@@ -17,10 +17,10 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))]
#![feature(cfg_select)]
#![feature(core_io_borrowed_buf)]
#![feature(if_let_guard)]
#![feature(map_try_insert)]
#![feature(negative_impls)]
#![feature(read_buf)]
+1 -1
View File
@@ -12,11 +12,11 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(default_field_values)]
#![feature(hash_set_entry)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iterator_try_reduce)]
#![feature(never_type)]
+1 -1
View File
@@ -6,9 +6,9 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iterator_try_collect)]
#![feature(never_type)]
// tidy-alphabetical-end
-1
View File
@@ -141,7 +141,6 @@
#![feature(freeze_impls)]
#![feature(fundamental)]
#![feature(funnel_shifts)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(intrinsics)]
#![feature(lang_items)]
-1
View File
@@ -289,7 +289,6 @@
#![feature(ffi_const)]
#![feature(formatting_options)]
#![feature(funnel_shifts)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
+1 -1
View File
@@ -1,5 +1,6 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(assert_matches))]
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/"
@@ -9,7 +10,6 @@
#![feature(box_patterns)]
#![feature(file_buffered)]
#![feature(formatting_options)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
#![feature(rustc_private)]
+1 -1
View File
@@ -1,9 +1,9 @@
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(control_flow_into_value)]
#![feature(exact_div)]
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_partition_in_place)]
#![feature(macro_metavar_expr_concat)]
+1 -1
View File
@@ -1,5 +1,5 @@
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(never_type)]
#![feature(rustc_private)]
@@ -1,6 +1,5 @@
//@check-pass
#![warn(clippy::match_like_matches_macro)]
#![feature(if_let_guard)]
#[expect(clippy::option_option)]
fn issue15841(opt: Option<Option<Option<i32>>>, value: i32) {
@@ -1,5 +1,4 @@
//@aux-build:proc_macros.rs
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]
#![warn(clippy::redundant_guards)]
@@ -1,5 +1,4 @@
//@aux-build:proc_macros.rs
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]
#![warn(clippy::redundant_guards)]
@@ -1,5 +1,5 @@
error: redundant guard
--> tests/ui/redundant_guards.rs:22:14
--> tests/ui/redundant_guards.rs:21:14
|
LL | x if x == 0.0 => todo!(),
| ^^^^^^^^
@@ -13,7 +13,7 @@ LL + 0.0 => todo!(),
|
error: redundant guard
--> tests/ui/redundant_guards.rs:29:14
--> tests/ui/redundant_guards.rs:28:14
|
LL | x if x == FloatWrapper(0.0) => todo!(),
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL + FloatWrapper(0.0) => todo!(),
|
error: redundant guard
--> tests/ui/redundant_guards.rs:45:20
--> tests/ui/redundant_guards.rs:44:20
|
LL | C(x, y) if let 1 = y => ..,
| ^^^^^^^^^
@@ -37,7 +37,7 @@ LL + C(x, 1) => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:52:20
--> tests/ui/redundant_guards.rs:51:20
|
LL | Some(x) if matches!(x, Some(1) if true) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL + Some(Some(1)) if true => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:54:20
--> tests/ui/redundant_guards.rs:53:20
|
LL | Some(x) if matches!(x, Some(1)) => {
| ^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL + Some(Some(1)) => {
|
error: redundant guard
--> tests/ui/redundant_guards.rs:59:20
--> tests/ui/redundant_guards.rs:58:20
|
LL | Some(x) if let Some(1) = x => ..,
| ^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL + Some(Some(1)) => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:61:20
--> tests/ui/redundant_guards.rs:60:20
|
LL | Some(x) if x == Some(2) => ..,
| ^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL + Some(Some(2)) => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:63:20
--> tests/ui/redundant_guards.rs:62:20
|
LL | Some(x) if Some(2) == x => ..,
| ^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL + Some(Some(2)) => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:89:20
--> tests/ui/redundant_guards.rs:88:20
|
LL | B { e } if matches!(e, Some(A(2))) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -109,7 +109,7 @@ LL + B { e: Some(A(2)) } => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:127:20
--> tests/ui/redundant_guards.rs:126:20
|
LL | E::A(y) if y == "not from an or pattern" => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL + E::A("not from an or pattern") => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:135:14
--> tests/ui/redundant_guards.rs:134:14
|
LL | x if matches!(x, Some(0)) => ..,
| ^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL + Some(0) => ..,
|
error: redundant guard
--> tests/ui/redundant_guards.rs:143:14
--> tests/ui/redundant_guards.rs:142:14
|
LL | i if i == -1 => {},
| ^^^^^^^
@@ -145,7 +145,7 @@ LL + -1 => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:145:14
--> tests/ui/redundant_guards.rs:144:14
|
LL | i if i == 1 => {},
| ^^^^^^
@@ -157,7 +157,7 @@ LL + 1 => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:208:28
--> tests/ui/redundant_guards.rs:207:28
|
LL | Some(ref x) if x == &1 => {},
| ^^^^^^^
@@ -169,7 +169,7 @@ LL + Some(1) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:210:28
--> tests/ui/redundant_guards.rs:209:28
|
LL | Some(ref x) if &1 == x => {},
| ^^^^^^^
@@ -181,7 +181,7 @@ LL + Some(1) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:212:28
--> tests/ui/redundant_guards.rs:211:28
|
LL | Some(ref x) if let &2 = x => {},
| ^^^^^^^^^^
@@ -193,7 +193,7 @@ LL + Some(2) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:214:28
--> tests/ui/redundant_guards.rs:213:28
|
LL | Some(ref x) if matches!(x, &3) => {},
| ^^^^^^^^^^^^^^^
@@ -205,7 +205,7 @@ LL + Some(3) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:235:32
--> tests/ui/redundant_guards.rs:234:32
|
LL | B { ref c, .. } if c == &1 => {},
| ^^^^^^^
@@ -217,7 +217,7 @@ LL + B { c: 1, .. } => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:237:32
--> tests/ui/redundant_guards.rs:236:32
|
LL | B { ref c, .. } if &1 == c => {},
| ^^^^^^^
@@ -229,7 +229,7 @@ LL + B { c: 1, .. } => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:239:32
--> tests/ui/redundant_guards.rs:238:32
|
LL | B { ref c, .. } if let &1 = c => {},
| ^^^^^^^^^^
@@ -241,7 +241,7 @@ LL + B { c: 1, .. } => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:241:32
--> tests/ui/redundant_guards.rs:240:32
|
LL | B { ref c, .. } if matches!(c, &1) => {},
| ^^^^^^^^^^^^^^^
@@ -253,7 +253,7 @@ LL + B { c: 1, .. } => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:252:26
--> tests/ui/redundant_guards.rs:251:26
|
LL | Some(Some(x)) if x.is_empty() => {},
| ^^^^^^^^^^^^
@@ -265,7 +265,7 @@ LL + Some(Some("")) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:264:26
--> tests/ui/redundant_guards.rs:263:26
|
LL | Some(Some(x)) if x.is_empty() => {},
| ^^^^^^^^^^^^
@@ -277,7 +277,7 @@ LL + Some(Some([])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:270:26
--> tests/ui/redundant_guards.rs:269:26
|
LL | Some(Some(x)) if x.is_empty() => {},
| ^^^^^^^^^^^^
@@ -289,7 +289,7 @@ LL + Some(Some([])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:282:26
--> tests/ui/redundant_guards.rs:281:26
|
LL | Some(Some(x)) if x.starts_with(&[]) => {},
| ^^^^^^^^^^^^^^^^^^
@@ -301,7 +301,7 @@ LL + Some(Some([..])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:288:26
--> tests/ui/redundant_guards.rs:287:26
|
LL | Some(Some(x)) if x.starts_with(&[1]) => {},
| ^^^^^^^^^^^^^^^^^^^
@@ -313,7 +313,7 @@ LL + Some(Some([1, ..])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:294:26
--> tests/ui/redundant_guards.rs:293:26
|
LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {},
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -325,7 +325,7 @@ LL + Some(Some([1, 2, ..])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:300:26
--> tests/ui/redundant_guards.rs:299:26
|
LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {},
| ^^^^^^^^^^^^^^^^^^^^
@@ -337,7 +337,7 @@ LL + Some(Some([.., 1, 2])) => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:323:18
--> tests/ui/redundant_guards.rs:322:18
|
LL | y if y.is_empty() => {},
| ^^^^^^^^^^^^
@@ -349,7 +349,7 @@ LL + "" => {},
|
error: redundant guard
--> tests/ui/redundant_guards.rs:342:22
--> tests/ui/redundant_guards.rs:341:22
|
LL | y if y.is_empty() => {},
| ^^^^^^^^^^^^
@@ -1,4 +1,3 @@
#![feature(if_let_guard)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
clippy::needless_bool,
@@ -1,4 +1,3 @@
#![feature(if_let_guard)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
clippy::needless_bool,
@@ -1,5 +1,5 @@
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:12:5
--> tests/ui/redundant_pattern_matching_option.rs:11:5
|
LL | matches!(maybe_some, None if !boolean)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (!boolean)`
@@ -8,55 +8,55 @@ LL | matches!(maybe_some, None if !boolean)
= help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:17:13
--> tests/ui/redundant_pattern_matching_option.rs:16:13
|
LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:33:12
--> tests/ui/redundant_pattern_matching_option.rs:32:12
|
LL | if let None = None::<()> {}
| -------^^^^------------- help: try: `if None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:36:12
--> tests/ui/redundant_pattern_matching_option.rs:35:12
|
LL | if let Some(_) = Some(42) {}
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:39:12
--> tests/ui/redundant_pattern_matching_option.rs:38:12
|
LL | if let Some(_) = Some(42) {
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:46:15
--> tests/ui/redundant_pattern_matching_option.rs:45:15
|
LL | while let Some(_) = Some(42) {}
| ----------^^^^^^^----------- help: try: `while Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:49:15
--> tests/ui/redundant_pattern_matching_option.rs:48:15
|
LL | while let None = Some(42) {}
| ----------^^^^----------- help: try: `while Some(42).is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:52:15
--> tests/ui/redundant_pattern_matching_option.rs:51:15
|
LL | while let None = None::<()> {}
| ----------^^^^------------- help: try: `while None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:56:15
--> tests/ui/redundant_pattern_matching_option.rs:55:15
|
LL | while let Some(_) = v.pop() {
| ----------^^^^^^^---------- help: try: `while v.pop().is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:65:5
--> tests/ui/redundant_pattern_matching_option.rs:64:5
|
LL | / match Some(42) {
LL | |
@@ -66,7 +66,7 @@ LL | | };
| |_____^ help: try: `Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:71:5
--> tests/ui/redundant_pattern_matching_option.rs:70:5
|
LL | / match None::<()> {
LL | |
@@ -76,7 +76,7 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:77:13
--> tests/ui/redundant_pattern_matching_option.rs:76:13
|
LL | let _ = match None::<()> {
| _____________^
@@ -87,55 +87,55 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:84:20
--> tests/ui/redundant_pattern_matching_option.rs:83:20
|
LL | let _ = if let Some(_) = opt { true } else { false };
| -------^^^^^^^------ help: try: `if opt.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:91:20
--> tests/ui/redundant_pattern_matching_option.rs:90:20
|
LL | let _ = if let Some(_) = gen_opt() {
| -------^^^^^^^------------ help: try: `if gen_opt().is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:94:19
--> tests/ui/redundant_pattern_matching_option.rs:93:19
|
LL | } else if let None = gen_opt() {
| -------^^^^------------ help: try: `if gen_opt().is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:101:12
--> tests/ui/redundant_pattern_matching_option.rs:100:12
|
LL | if let Some(..) = gen_opt() {}
| -------^^^^^^^^------------ help: try: `if gen_opt().is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:117:12
--> tests/ui/redundant_pattern_matching_option.rs:116:12
|
LL | if let Some(_) = Some(42) {}
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:120:12
--> tests/ui/redundant_pattern_matching_option.rs:119:12
|
LL | if let None = None::<()> {}
| -------^^^^------------- help: try: `if None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:123:15
--> tests/ui/redundant_pattern_matching_option.rs:122:15
|
LL | while let Some(_) = Some(42) {}
| ----------^^^^^^^----------- help: try: `while Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:126:15
--> tests/ui/redundant_pattern_matching_option.rs:125:15
|
LL | while let None = None::<()> {}
| ----------^^^^------------- help: try: `while None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:129:5
--> tests/ui/redundant_pattern_matching_option.rs:128:5
|
LL | / match Some(42) {
LL | |
@@ -145,7 +145,7 @@ LL | | };
| |_____^ help: try: `Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:135:5
--> tests/ui/redundant_pattern_matching_option.rs:134:5
|
LL | / match None::<()> {
LL | |
@@ -155,19 +155,19 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:144:12
--> tests/ui/redundant_pattern_matching_option.rs:143:12
|
LL | if let None = *(&None::<()>) {}
| -------^^^^----------------- help: try: `if (&None::<()>).is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:146:12
--> tests/ui/redundant_pattern_matching_option.rs:145:12
|
LL | if let None = *&None::<()> {}
| -------^^^^--------------- help: try: `if (&None::<()>).is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:153:5
--> tests/ui/redundant_pattern_matching_option.rs:152:5
|
LL | / match x {
LL | |
@@ -177,7 +177,7 @@ LL | | };
| |_____^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:159:5
--> tests/ui/redundant_pattern_matching_option.rs:158:5
|
LL | / match x {
LL | |
@@ -187,7 +187,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:165:5
--> tests/ui/redundant_pattern_matching_option.rs:164:5
|
LL | / match x {
LL | |
@@ -197,7 +197,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:171:5
--> tests/ui/redundant_pattern_matching_option.rs:170:5
|
LL | / match x {
LL | |
@@ -207,43 +207,43 @@ LL | | };
| |_____^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:187:13
--> tests/ui/redundant_pattern_matching_option.rs:186:13
|
LL | let _ = matches!(x, Some(_));
| ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:190:13
--> tests/ui/redundant_pattern_matching_option.rs:189:13
|
LL | let _ = matches!(x, None);
| ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()`
error: redundant pattern matching, consider using `is_none()`
--> tests/ui/redundant_pattern_matching_option.rs:201:17
--> tests/ui/redundant_pattern_matching_option.rs:200:17
|
LL | let _ = matches!(*p, None);
| ^^^^^^^^^^^^^^^^^^ help: try: `(*p).is_none()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:209:16
--> tests/ui/redundant_pattern_matching_option.rs:208:16
|
LL | if let Some(_) = x? {
| -------^^^^^^^----- help: try: `if x?.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:229:16
--> tests/ui/redundant_pattern_matching_option.rs:228:16
|
LL | if let Some(_) = x.await {
| -------^^^^^^^---------- help: try: `if x.await.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:242:12
--> tests/ui/redundant_pattern_matching_option.rs:241:12
|
LL | if let Some(_) = (x! {}) {};
| -------^^^^^^^---------- help: try: `if x! {}.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> tests/ui/redundant_pattern_matching_option.rs:244:15
--> tests/ui/redundant_pattern_matching_option.rs:243:15
|
LL | while let Some(_) = (x! {}) {}
| ----------^^^^^^^---------- help: try: `while x! {}.is_some()`
+1 -1
View File
@@ -1,3 +1,4 @@
#![cfg_attr(bootstrap, feature(if_let_guard))]
#![feature(abort_unwind)]
#![feature(cfg_select)]
#![feature(rustc_private)]
@@ -7,7 +8,6 @@
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(io_error_more)]
#![feature(if_let_guard)]
#![feature(variant_count)]
#![feature(yeet_expr)]
#![feature(nonzero_ops)]
-1
View File
@@ -2414,7 +2414,6 @@ ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs
ui/rfcs/rfc-2497-if-let-chains/issue-88498.rs
ui/rfcs/rfc-2497-if-let-chains/issue-90722.rs
ui/rfcs/rfc-2497-if-let-chains/issue-92145.rs
ui/rfcs/rfc-2497-if-let-chains/issue-93150.rs
ui/rfcs/rfc-2497-if-let-chains/issue-99938.rs
ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
@@ -1,8 +1,6 @@
//@ build-pass
//@ edition:2018
#![feature(if_let_guard)]
static A: [i32; 5] = [1, 2, 3, 4, 5];
async fn fun() {
@@ -1,7 +1,6 @@
//@ build-pass
//@ edition:2018
#![feature(if_let_guard)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
@@ -1,8 +1,6 @@
//@ check-pass
//@ edition:2018
#![feature(if_let_guard)]
fn main() {}
struct StructA {}
-2
View File
@@ -1,7 +1,5 @@
//@ run-pass
#![feature(if_let_guard)]
enum Foo {
A,
B,
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
fn foo(_:String) {}
fn main()
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `my_str`
--> $DIR/borrowck-drop-from-guard.rs:11:23
--> $DIR/borrowck-drop-from-guard.rs:9:23
|
LL | let my_str = "hello".to_owned();
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
@@ -16,7 +16,7 @@ LL | Some(_) if { drop(my_str.clone()); false } => {}
| ++++++++
error[E0382]: use of moved value: `my_str`
--> $DIR/borrowck-drop-from-guard.rs:18:23
--> $DIR/borrowck-drop-from-guard.rs:16:23
|
LL | let my_str = "hello".to_owned();
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
enum Enum<'a> {
A(&'a isize),
B(bool),
@@ -1,5 +1,5 @@
error[E0510]: cannot assign `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:12:25
--> $DIR/borrowck-mutate-in-guard.rs:10:25
|
LL | match x {
| - value is immutable in match guard
@@ -7,7 +7,7 @@ LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
| ^^^^^^^^^^^^^^^^^^ cannot assign
error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:14:33
--> $DIR/borrowck-mutate-in-guard.rs:12:33
|
LL | match x {
| - value is immutable in match guard
@@ -16,7 +16,7 @@ LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
| ^^^^^^ cannot mutably borrow
error[E0510]: cannot assign `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:25:40
--> $DIR/borrowck-mutate-in-guard.rs:23:40
|
LL | match x {
| - value is immutable in match guard
@@ -24,7 +24,7 @@ LL | Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1,
| ^^^^^^^^^^^^^^^^^^ cannot assign
error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:27:48
--> $DIR/borrowck-mutate-in-guard.rs:25:48
|
LL | match x {
| - value is immutable in match guard
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
fn main() {
let a = Some("...".to_owned());
let b = match a {
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a`
--> $DIR/issue-31287-drop-in-guard.rs:7:9
--> $DIR/issue-31287-drop-in-guard.rs:5:9
|
LL | let a = Some("...".to_owned());
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
@@ -15,7 +15,7 @@ LL | Some(_) if { drop(a.clone()); false } => None,
| ++++++++
error[E0382]: use of moved value: `a`
--> $DIR/issue-31287-drop-in-guard.rs:13:9
--> $DIR/issue-31287-drop-in-guard.rs:11:9
|
LL | let a = Some("...".to_owned());
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
@@ -1,6 +1,5 @@
//@ edition:2021
//@ run-pass
#![feature(if_let_guard)]
#[allow(unused_must_use)]
#[allow(dead_code)]
@@ -1,5 +1,5 @@
warning: irrefutable `if let` guard pattern
--> $DIR/issue-88118-2.rs:10:25
--> $DIR/issue-88118-2.rs:9:25
|
LL | Registry if let _ = registry.try_find_description() => { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error[E0505]: cannot move out of `value` because it is borrowed
--> $DIR/if-let-guards-errors.rs:16:13
--> $DIR/if-let-guards-errors.rs:15:13
|
LL | let f = |x: &E| {
| ------- borrow of `value` occurs here
@@ -14,7 +14,7 @@ LL | drop(f);
| - borrow later used here
error[E0382]: use of moved value: `value`
--> $DIR/if-let-guards-errors.rs:28:13
--> $DIR/if-let-guards-errors.rs:27:13
|
LL | fn if_let_move(value: Box<E>) {
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
@@ -28,7 +28,7 @@ LL | let x = value;
| ^^^^^ value used here after move
|
note: if `E` implemented `Clone`, you could clone the value
--> $DIR/if-let-guards-errors.rs:32:1
--> $DIR/if-let-guards-errors.rs:31:1
|
LL | E::Number(_) if let E::String(s) = *value => { }
| ------ you could clone this value
@@ -1,5 +1,5 @@
error[E0505]: cannot move out of `value` because it is borrowed
--> $DIR/if-let-guards-errors.rs:16:13
--> $DIR/if-let-guards-errors.rs:15:13
|
LL | let f = |x: &E| {
| ------- borrow of `*value` occurs here
@@ -14,7 +14,7 @@ LL | drop(f);
| - borrow later used here
error[E0382]: use of moved value: `value`
--> $DIR/if-let-guards-errors.rs:28:13
--> $DIR/if-let-guards-errors.rs:27:13
|
LL | fn if_let_move(value: Box<E>) {
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
@@ -28,7 +28,7 @@ LL | let x = value;
| ^^^^^ value used here after move
|
note: if `E` implemented `Clone`, you could clone the value
--> $DIR/if-let-guards-errors.rs:32:1
--> $DIR/if-let-guards-errors.rs:31:1
|
LL | E::Number(_) if let E::String(s) = *value => { }
| ------ you could clone this value
@@ -3,7 +3,6 @@
//@[e2018] edition:2018
//@[e2021] edition:2021
#![feature(if_let_guard)]
#![allow(irrefutable_let_patterns)]
fn if_let_ref_mut(mut value: Box<E>) {
@@ -4,7 +4,6 @@
//@[e2018] edition:2018
//@[e2021] edition:2021
#![feature(if_let_guard)]
#![allow(irrefutable_let_patterns)]
fn if_let_underscore(value: Box<E>) {
@@ -10,8 +10,6 @@
// Thus, `&'_ u8` should be included in type signature
// of the underlying coroutine.
#![feature(if_let_guard)]
async fn f() -> u8 { 1 }
async fn foo() -> [bool; 10] { [false; 10] }
@@ -3,8 +3,6 @@
//@ edition: 2024
//@ run-pass
#![feature(if_let_guard)]
fn t_if_let_chains_then() {
let e = Events::new();
_ = if e.ok(1).is_ok()
@@ -27,7 +27,6 @@
//@ [e2024] edition: 2024
//@ run-pass
#![feature(if_let_guard)]
#![cfg_attr(e2021, warn(rust_2024_compatibility))]
fn t_bindings() {
@@ -1,5 +1,5 @@
warning: relative drop order changing in Rust 2024
--> $DIR/drop-order-comparisons.rs:79:9
--> $DIR/drop-order-comparisons.rs:78:9
|
LL | _ = ({
| _________-
@@ -29,35 +29,35 @@ LL | | }, e.mark(3), e.ok(4));
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#3` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `_v` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
note: the lint level is defined here
--> $DIR/drop-order-comparisons.rs:31:25
--> $DIR/drop-order-comparisons.rs:30:25
|
LL | #![cfg_attr(e2021, warn(rust_2024_compatibility))]
| ^^^^^^^^^^^^^^^^^^^^^^^
= note: `#[warn(tail_expr_drop_order)]` implied by `#[warn(rust_2024_compatibility)]`
warning: relative drop order changing in Rust 2024
--> $DIR/drop-order-comparisons.rs:103:45
--> $DIR/drop-order-comparisons.rs:102:45
|
LL | _ = ({
| _________-
@@ -77,19 +77,19 @@ LL | | }, e.mark(1), e.ok(4));
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
--> $DIR/drop-order-comparisons.rs:103:19
--> $DIR/drop-order-comparisons.rs:102:19
|
LL | _ = ({
| _________-
@@ -109,19 +109,19 @@ LL | | }, e.mark(1), e.ok(4));
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
--> $DIR/drop-order-comparisons.rs:224:24
--> $DIR/drop-order-comparisons.rs:223:24
|
LL | _ = ({
| _________-
@@ -141,19 +141,19 @@ LL | | }, e.mark(2), e.ok(3));
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
--> $DIR/drop-order-comparisons.rs:250:24
--> $DIR/drop-order-comparisons.rs:249:24
|
LL | _ = ({
| _________-
@@ -173,19 +173,19 @@ LL | | }, e.mark(2), e.ok(3));
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:126:13
--> $DIR/drop-order-comparisons.rs:125:13
|
LL | _ = (if let Ok(_) = e.ok(4).as_ref() {
| ^^^^^^^^^^^^-------^^^^^^^^^
@@ -195,12 +195,12 @@ LL | _ = (if let Ok(_) = e.ok(4).as_ref() {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:130:5
--> $DIR/drop-order-comparisons.rs:129:5
|
LL | }, e.mark(2), e.ok(3));
| ^
@@ -215,7 +215,7 @@ LL ~ } _ => {}}, e.mark(2), e.ok(3));
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:148:13
--> $DIR/drop-order-comparisons.rs:147:13
|
LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else {
| ^^^^^^^^^^^^--------^^^^^^^^^
@@ -225,12 +225,12 @@ LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:148:44
--> $DIR/drop-order-comparisons.rs:147:44
|
LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else {
| ^
@@ -244,7 +244,7 @@ LL ~ }}, e.mark(2), e.ok(3));
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:250:12
--> $DIR/drop-order-comparisons.rs:249:12
|
LL | if let Ok(_) = e.err(4).as_ref() {} else {
| ^^^^^^^^^^^^--------^^^^^^^^^
@@ -254,12 +254,12 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:250:43
--> $DIR/drop-order-comparisons.rs:249:43
|
LL | if let Ok(_) = e.err(4).as_ref() {} else {
| ^
@@ -273,7 +273,7 @@ LL ~ }}
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:321:12
--> $DIR/drop-order-comparisons.rs:320:12
|
LL | if let true = e.err(9).is_ok() {} else {
| ^^^^^^^^^^^--------^^^^^^^^
@@ -283,12 +283,12 @@ LL | if let true = e.err(9).is_ok() {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:321:41
--> $DIR/drop-order-comparisons.rs:320:41
|
LL | if let true = e.err(9).is_ok() {} else {
| ^
@@ -302,7 +302,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:324:12
--> $DIR/drop-order-comparisons.rs:323:12
|
LL | if let Ok(_v) = e.err(8) {} else {
| ^^^^^^^^^^^^^--------
@@ -312,12 +312,12 @@ LL | if let Ok(_v) = e.err(8) {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:324:35
--> $DIR/drop-order-comparisons.rs:323:35
|
LL | if let Ok(_v) = e.err(8) {} else {
| ^
@@ -331,7 +331,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:327:12
--> $DIR/drop-order-comparisons.rs:326:12
|
LL | if let Ok(_) = e.err(7) {} else {
| ^^^^^^^^^^^^--------
@@ -341,12 +341,12 @@ LL | if let Ok(_) = e.err(7) {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:327:34
--> $DIR/drop-order-comparisons.rs:326:34
|
LL | if let Ok(_) = e.err(7) {} else {
| ^
@@ -360,7 +360,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:330:12
--> $DIR/drop-order-comparisons.rs:329:12
|
LL | if let Ok(_) = e.err(6).as_ref() {} else {
| ^^^^^^^^^^^^--------^^^^^^^^^
@@ -370,12 +370,12 @@ LL | if let Ok(_) = e.err(6).as_ref() {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:330:43
--> $DIR/drop-order-comparisons.rs:329:43
|
LL | if let Ok(_) = e.err(6).as_ref() {} else {
| ^
@@ -389,7 +389,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:334:12
--> $DIR/drop-order-comparisons.rs:333:12
|
LL | if let Ok(_v) = e.err(5) {} else {
| ^^^^^^^^^^^^^--------
@@ -399,12 +399,12 @@ LL | if let Ok(_v) = e.err(5) {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:334:35
--> $DIR/drop-order-comparisons.rs:333:35
|
LL | if let Ok(_v) = e.err(5) {} else {
| ^
@@ -418,7 +418,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:337:12
--> $DIR/drop-order-comparisons.rs:336:12
|
LL | if let Ok(_) = e.err(4) {} else {
| ^^^^^^^^^^^^--------
@@ -428,12 +428,12 @@ LL | if let Ok(_) = e.err(4) {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:337:34
--> $DIR/drop-order-comparisons.rs:336:34
|
LL | if let Ok(_) = e.err(4) {} else {
| ^
@@ -447,7 +447,7 @@ LL ~ }}}}}}}}};
|
warning: `if let` assigns a shorter lifetime since Edition 2024
--> $DIR/drop-order-comparisons.rs:373:12
--> $DIR/drop-order-comparisons.rs:372:12
|
LL | if let Ok(_) = e.err(4).as_ref() {} else {
| ^^^^^^^^^^^^--------^^^^^^^^^
@@ -457,12 +457,12 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
--> $DIR/drop-order-comparisons.rs:503:1
|
LL | impl<'b> Drop for LogDrop<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:373:43
--> $DIR/drop-order-comparisons.rs:372:43
|
LL | if let Ok(_) = e.err(4).as_ref() {} else {
| ^
-1
View File
@@ -27,7 +27,6 @@
//@ [e2024] edition: 2024
//@ run-pass
#![feature(if_let_guard)]
#![cfg_attr(e2021, warn(rust_2024_compatibility))]
fn t_bindings() {
-1
View File
@@ -4,7 +4,6 @@
//@ ignore-backends: gcc
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
#![feature(if_let_guard)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
+229
View File
@@ -0,0 +1,229 @@
//! This demonstrates a surprising behavior in `if_let_guards`, as
//! implemented, that was found by dianne, and also was questioned in
//! the Reference PR by ehuss.
//!
//! See:
//!
//! - https://github.com/rust-lang/rust/pull/141295
//!
//! Author: TC
//! Author: dianne
//! Date: 2025-06-12
//@ run-pass
//@ edition: 2024
#![allow(irrefutable_let_patterns, unreachable_patterns)]
use core::{cell::RefCell, ops::Drop};
fn main() {
// The unexpected behavior.
// assert_drop_order(1..=3, |o| match (o.log(2), o.log(1)) {
// (_x, _y)
// if let _z = o.log(3)
// && true => {}
// _ => unreachable!(),
// });
assert_drop_order(1..=3, |o| match (o.log(2), o.log(3)) {
(_x, _y)
if let _z = o.log(1)
&& false =>
{
unreachable!()
}
_ => (),
});
// With temporaries in guard.
// assert_drop_order(1..=3, |o| match (o.log(2), o.log(1)) {
// (_x, _y)
// if let _z = o.log(3).as_true()
// && true => {}
// _ => unreachable!(),
// });
assert_drop_order(1..=3, |o| match (o.log(2), o.log(3)) {
(_x, _y)
if let _z = o.log(1).as_true()
&& false =>
{
unreachable!()
}
_ => (),
});
// With temporaries in match scrutinee.
assert_drop_order(1..=3, |o| {
match (o.log(3).as_true(), o.log(2).as_true()) {
(_x, _y)
if let _z = o.log(1).as_true()
&& true => {}
_ => unreachable!(),
}
});
assert_drop_order(1..=3, |o| {
match (o.log(3).as_true(), o.log(2).as_true()) {
(_x, _y)
if let _z = o.log(1).as_true()
&& false =>
{
unreachable!()
}
_ => (),
}
});
// Control with inner if let.
assert_drop_order(1..=3, |o| match (o.log(3), o.log(2)) {
(_x, _y) => {
if let _z = o.log(1)
&& true
{}
}
_ => unreachable!(),
});
assert_drop_order(1..=3, |o| match (o.log(3), o.log(2)) {
(_x, _y) => {
if let _z = o.log(1)
&& false
{
unreachable!()
}
}
_ => (),
});
// Control of drop before next arm.
assert_drop_order(1..=4, |o| match (o.log(3), o.log(4)) {
(_x, _y)
if let _z = o.log(1)
&& false => {}
_ if let _z = o.log(2) => {}
_ => unreachable!(),
});
// Control of values in guards.
assert_drop_order(1..=3, |o| match (o.log(3), o.log(2)) {
(_x, _y)
if {
o.log(1);
true
} && true => {}
_ => unreachable!(),
});
assert_drop_order(1..=3, |o| match (o.log(2), o.log(3)) {
(_x, _y)
if {
o.log(1);
true
} && false =>
{
unreachable!()
}
_ => (),
});
// Control of temporaries in guards.
assert_drop_order(1..=3, |o| match (o.log(3), o.log(2)) {
(_x, _y) if o.log(1).as_true() && true => {}
_ => unreachable!(),
});
assert_drop_order(1..=3, |o| match (o.log(2), o.log(3)) {
(_x, _y) if o.log(1).as_true() && false => {
unreachable!()
}
_ => (),
});
// Control of order on guard success.
assert_drop_order(1..=2, |o| match (o.log(2), o.log(1)) {
(_x, _y) if true => {}
_ => unreachable!(),
});
assert_drop_order(1..=2, |o| match (o.log(1), o.log(2)) {
(_x, _y) if false => {
unreachable!()
}
_ => (),
});
// Control of order on guard success when used.
assert_drop_order(1..=2, |o| match (o.log(2), o.log(1)) {
(_x, _y)
if {
_ = (&_x, &_y);
true
} && true => {}
_ => unreachable!(),
});
assert_drop_order(1..=2, |o| match (o.log(1), o.log(2)) {
(_x, _y)
if {
_ = (&_x, &_y);
true
} && false =>
{
unreachable!()
}
_ => (),
});
// Control of temporaries in match scrutinee.
assert_drop_order(1..=2, |o| {
match (o.log(2).as_true(), o.log(1).as_true()) {
(_x, _y) if true => {}
_ => unreachable!(),
}
});
assert_drop_order(1..=2, |o| {
match (o.log(2).as_true(), o.log(1).as_true()) {
(_x, _y) if false => {
unreachable!()
}
_ => (),
}
});
// Control of issue 142057.
//
// See:
//
// - https://github.com/rust-lang/rust/issues/142057
assert_drop_order(1..=2, |o| {
match (o.log(1), o.log(2).as_true()) {
(mut _x, ref _y) if true => {}
_ => unreachable!(),
}
});
assert_drop_order(1..=2, |o| {
match (o.log(1), o.log(2).as_true()) {
(mut _x, ref _y) => {}
_ => unreachable!(),
}
});
}
// # Test scaffolding...
struct DropOrder(RefCell<Vec<u64>>);
struct LogDrop<'o>(&'o DropOrder, u64);
impl DropOrder {
fn log(&self, n: u64) -> LogDrop<'_> {
LogDrop(self, n)
}
}
impl<'o> LogDrop<'o> {
fn as_true(&self) -> bool {
true
}
}
impl<'o> Drop for LogDrop<'o> {
fn drop(&mut self) {
self.0 .0.borrow_mut().push(self.1);
}
}
#[track_caller]
fn assert_drop_order(
ex: impl IntoIterator<Item = u64>,
f: impl Fn(&DropOrder),
) {
let order = DropOrder(RefCell::new(Vec::new()));
f(&order);
let order = order.0.into_inner();
let expected: Vec<u64> = ex.into_iter().collect();
assert_eq!(order, expected);
}
-1
View File
@@ -7,7 +7,6 @@
//@ [e2024] edition: 2024
//@ run-pass
#![feature(if_let_guard)]
#![deny(rust_2024_compatibility)]
use core::{cell::RefCell, ops::Drop};
-1
View File
@@ -6,7 +6,6 @@
//@ [e2021] edition: 2021
//@ [e2024] edition: 2024
#![feature(if_let_guard)]
#![feature(super_let)]
#![expect(irrefutable_let_patterns)]
-2
View File
@@ -1,7 +1,5 @@
// test for https://github.com/rust-lang/rust/issues/29723
#![feature(if_let_guard)]
fn main() {
let s = String::new();
let _s = match 0 {
+2 -2
View File
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `s`
--> $DIR/issue-29723.rs:12:13
--> $DIR/issue-29723.rs:10:13
|
LL | let s = String::new();
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
@@ -16,7 +16,7 @@ LL | 0 if { drop(s.clone()); false } => String::from("oops"),
| ++++++++
error[E0382]: use of moved value: `s`
--> $DIR/issue-29723.rs:20:14
--> $DIR/issue-29723.rs:18:14
|
LL | let s = String::new();
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
-1
View File
@@ -1,4 +1,3 @@
#![feature(if_let_guard)]
#![allow(unused, non_snake_case)]
enum E {
+4 -4
View File
@@ -1,17 +1,17 @@
error[E0170]: pattern binding `A` is named the same as one of the variants of the type `E`
--> $DIR/lint-match-arms-2.rs:12:9
--> $DIR/lint-match-arms-2.rs:11:9
|
LL | A => {}
| ^ help: to match on the variant, qualify the path: `E::A`
|
note: the lint level is defined here
--> $DIR/lint-match-arms-2.rs:11:16
--> $DIR/lint-match-arms-2.rs:10:16
|
LL | #[deny(bindings_with_variant_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: irrefutable `if let` guard pattern
--> $DIR/lint-match-arms-2.rs:18:14
--> $DIR/lint-match-arms-2.rs:17:14
|
LL | a if let b = a => {}
| ^^^^^^^^^
@@ -19,7 +19,7 @@ LL | a if let b = a => {}
= note: this pattern will always match, so the guard is useless
= help: consider removing the guard and adding a `let` inside the match arm
note: the lint level is defined here
--> $DIR/lint-match-arms-2.rs:17:16
--> $DIR/lint-match-arms-2.rs:16:16
|
LL | #[deny(irrefutable_let_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1,4 +1,3 @@
#![feature(if_let_guard)]
#![deny(unused_variables)]
fn main() {
@@ -1,11 +1,11 @@
error: unused variable: `b`
--> $DIR/issue-119383-if-let-guard.rs:6:24
--> $DIR/issue-119383-if-let-guard.rs:5:24
|
LL | () if let Some(b) = Some(()) => {}
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: the lint level is defined here
--> $DIR/issue-119383-if-let-guard.rs:2:9
--> $DIR/issue-119383-if-let-guard.rs:1:9
|
LL | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
-1
View File
@@ -10,7 +10,6 @@
#![feature(coroutines)]
#![feature(decl_macro)]
#![feature(explicit_tail_calls)]
#![feature(if_let_guard)]
#![feature(more_qualified_paths)]
#![feature(never_patterns)]
#![feature(trait_alias)]
@@ -7,7 +7,6 @@
// See `mir_drop_order.rs` for more information
#![feature(if_let_guard)]
#![allow(irrefutable_let_patterns)]
use std::cell::RefCell;
@@ -5,8 +5,6 @@
// See further discussion on rust-lang/rust#24535,
// rust-lang/rfcs#1006, and rust-lang/rfcs#107
#![feature(if_let_guard)]
fn main() {
rust_issue_24535();
rfcs_issue_1006_1();
@@ -7,8 +7,6 @@
// reaches the panic code when executed, despite the compiler warning
// about that match arm being unreachable.
#![feature(if_let_guard)]
fn main() {
let b = &mut true;
match b {
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:14:5
--> $DIR/issue-27282-move-match-input-into-guard.rs:12:5
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
@@ -12,7 +12,7 @@ LL | _ if { (|| { let bar = b; *bar = false; })();
| value moved into closure here
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:24:5
--> $DIR/issue-27282-move-match-input-into-guard.rs:22:5
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
@@ -2,8 +2,6 @@
// mutable borrows in match guards by hiding the mutable borrow in a
// guard behind a move (of the ref mut pattern id) within a closure.
#![feature(if_let_guard)]
fn main() {
match Some(&4) {
None => {},
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
|
LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -9,7 +9,7 @@ LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {},
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:17:34
|
LL | if let Some(()) = { (|| { let mut bar = foo; bar.take() })(); None } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
fn main() {
match Some(&4) {
None => {},
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-mutation-in-guard.rs:8:18
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -9,7 +9,7 @@ LL | (|| { let bar = foo; bar.take() })();
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-mutation-in-guard.rs:20:18
--> $DIR/issue-27282-mutation-in-guard.rs:18:18
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -6,8 +6,6 @@
// reject it. But I want to make sure that we continue to reject it
// (under NLL) even when that conservative check goes away.
#![feature(if_let_guard)]
fn main() {
let mut b = &mut true;
match b {
@@ -1,5 +1,5 @@
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:15:25
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:13:25
|
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
| ^^ -- mutable borrow occurs due to use of `r` in closure
@@ -9,7 +9,7 @@ LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
= note: variables bound in patterns are immutable until the end of the pattern guard
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:25:40
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:23:40
|
LL | ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })();
| ^^ -- mutable borrow occurs due to use of `r` in closure
-2
View File
@@ -1,8 +1,6 @@
// Test that we have enough false edges to avoid exposing the exact matching
// algorithm in borrow checking.
#![feature(if_let_guard)]
#[rustfmt::skip]
fn all_patterns_are_tested() {
// Even though `x` is never actually moved out of, we don't want borrowck results to be based on
+12 -12
View File
@@ -1,5 +1,5 @@
warning: irrefutable `if let` pattern
--> $DIR/match-cfg-fake-edges.rs:19:8
--> $DIR/match-cfg-fake-edges.rs:17:8
|
LL | if let _ = true {
| ^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | if let _ = true {
= note: `#[warn(irrefutable_let_patterns)]` on by default
error[E0382]: use of moved value: `x`
--> $DIR/match-cfg-fake-edges.rs:16:10
--> $DIR/match-cfg-fake-edges.rs:14:10
|
LL | let x = String::new();
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
@@ -26,7 +26,7 @@ LL | _ => drop(x.clone()),
| ++++++++
error[E0382]: use of moved value: `x`
--> $DIR/match-cfg-fake-edges.rs:24:10
--> $DIR/match-cfg-fake-edges.rs:22:10
|
LL | let x = String::new();
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
@@ -43,7 +43,7 @@ LL | drop(x.clone())
| ++++++++
error[E0382]: borrow of moved value: `x.0`
--> $DIR/match-cfg-fake-edges.rs:30:5
--> $DIR/match-cfg-fake-edges.rs:28:5
|
LL | (y, _) | (_, y) => (),
| - value moved here
@@ -58,7 +58,7 @@ LL | (ref y, _) | (_, y) => (),
| +++
error[E0382]: borrow of moved value: `x.1`
--> $DIR/match-cfg-fake-edges.rs:32:5
--> $DIR/match-cfg-fake-edges.rs:30:5
|
LL | (y, _) | (_, y) => (),
| - value moved here
@@ -73,7 +73,7 @@ LL | (y, _) | (_, ref y) => (),
| +++
error[E0382]: borrow of moved value: `x.0`
--> $DIR/match-cfg-fake-edges.rs:36:5
--> $DIR/match-cfg-fake-edges.rs:34:5
|
LL | let ((y, _) | (_, y)) = x;
| - value moved here
@@ -87,7 +87,7 @@ LL | let ((ref y, _) | (_, y)) = x;
| +++
error[E0382]: borrow of moved value: `x.1`
--> $DIR/match-cfg-fake-edges.rs:38:5
--> $DIR/match-cfg-fake-edges.rs:36:5
|
LL | let ((y, _) | (_, y)) = x;
| - value moved here
@@ -102,7 +102,7 @@ LL | let ((y, _) | (_, ref y)) = x;
| +++
error[E0381]: used binding `x` is possibly-uninitialized
--> $DIR/match-cfg-fake-edges.rs:72:19
--> $DIR/match-cfg-fake-edges.rs:70:19
|
LL | let x;
| - binding declared here but left uninitialized
@@ -113,7 +113,7 @@ LL | _ => drop(x),
| if this pattern is matched, `x` is not initialized
error[E0381]: used binding `x` isn't initialized
--> $DIR/match-cfg-fake-edges.rs:79:16
--> $DIR/match-cfg-fake-edges.rs:77:16
|
LL | let x;
| - binding declared here but left uninitialized
@@ -130,7 +130,7 @@ LL | let x = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/match-cfg-fake-edges.rs:86:31
--> $DIR/match-cfg-fake-edges.rs:84:31
|
LL | let x;
| - binding declared here but left uninitialized
@@ -146,7 +146,7 @@ LL | let x = 42;
| ++++
error[E0382]: use of moved value: `x`
--> $DIR/match-cfg-fake-edges.rs:99:22
--> $DIR/match-cfg-fake-edges.rs:97:22
|
LL | let x = String::new();
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
@@ -163,7 +163,7 @@ LL | false if { drop(x.clone()); true } => {},
| ++++++++
error[E0382]: use of moved value: `x`
--> $DIR/match-cfg-fake-edges.rs:114:22
--> $DIR/match-cfg-fake-edges.rs:112:22
|
LL | let x = String::new();
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
@@ -1,4 +1,3 @@
#![feature(if_let_guard)]
#![allow(unused_mut)]
// Here is arielb1's basic example from rust-lang/rust#27282
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/match-guards-always-borrow.rs:11:14
--> $DIR/match-guards-always-borrow.rs:10:14
|
LL | (|| { let mut bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -9,7 +9,7 @@ LL | (|| { let mut bar = foo; bar.take() })();
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/match-guards-always-borrow.rs:20:14
--> $DIR/match-guards-always-borrow.rs:19:14
|
LL | (|| { let mut bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
@@ -5,8 +5,6 @@
// Test that we don't allow mutating the value being matched on in a way that
// changes which patterns it matches, until we have chosen an arm.
#![feature(if_let_guard)]
fn ok_mutation_in_if_guard(mut q: i32) {
match q {
// OK, mutation doesn't change which patterns g matches
@@ -1,5 +1,5 @@
error[E0510]: cannot assign `q` in match guard
--> $DIR/match-guards-partially-borrow.rs:100:13
--> $DIR/match-guards-partially-borrow.rs:98:13
|
LL | match q {
| - value is immutable in match guard
@@ -8,7 +8,7 @@ LL | q = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot assign `q` in match guard
--> $DIR/match-guards-partially-borrow.rs:111:13
--> $DIR/match-guards-partially-borrow.rs:109:13
|
LL | match q {
| - value is immutable in match guard
@@ -17,7 +17,7 @@ LL | q = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot assign `r` in match guard
--> $DIR/match-guards-partially-borrow.rs:123:13
--> $DIR/match-guards-partially-borrow.rs:121:13
|
LL | match r {
| - value is immutable in match guard
@@ -26,7 +26,7 @@ LL | r = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot assign `r` in match guard
--> $DIR/match-guards-partially-borrow.rs:135:13
--> $DIR/match-guards-partially-borrow.rs:133:13
|
LL | match r {
| - value is immutable in match guard
@@ -35,7 +35,7 @@ LL | r = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot assign `t` in match guard
--> $DIR/match-guards-partially-borrow.rs:172:13
--> $DIR/match-guards-partially-borrow.rs:170:13
|
LL | match t {
| - value is immutable in match guard
@@ -44,7 +44,7 @@ LL | t = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot assign `t` in match guard
--> $DIR/match-guards-partially-borrow.rs:183:13
--> $DIR/match-guards-partially-borrow.rs:181:13
|
LL | match t {
| - value is immutable in match guard
@@ -53,7 +53,7 @@ LL | t = true;
| ^^^^^^^^ cannot assign
error[E0510]: cannot mutably borrow `x.0` in match guard
--> $DIR/match-guards-partially-borrow.rs:197:22
--> $DIR/match-guards-partially-borrow.rs:195:22
|
LL | match x {
| - value is immutable in match guard
@@ -62,7 +62,7 @@ LL | Some(ref mut r) => *r = None,
| ^^^^^^^^^ cannot mutably borrow
error[E0510]: cannot mutably borrow `x.0` in match guard
--> $DIR/match-guards-partially-borrow.rs:213:22
--> $DIR/match-guards-partially-borrow.rs:211:22
|
LL | match x {
| - value is immutable in match guard
@@ -71,7 +71,7 @@ LL | Some(ref mut r) => *r = None,
| ^^^^^^^^^ cannot mutably borrow
error[E0506]: cannot assign to `t` because it is borrowed
--> $DIR/match-guards-partially-borrow.rs:225:13
--> $DIR/match-guards-partially-borrow.rs:223:13
|
LL | s if {
| - `t` is borrowed here
@@ -82,7 +82,7 @@ LL | } => (), // What value should `s` have in the arm?
| - borrow later used here
error[E0506]: cannot assign to `t` because it is borrowed
--> $DIR/match-guards-partially-borrow.rs:235:13
--> $DIR/match-guards-partially-borrow.rs:233:13
|
LL | s if let Some(()) = {
| - `t` is borrowed here
@@ -93,7 +93,7 @@ LL | } => (), // What value should `s` have in the arm?
| - borrow later used here
error[E0510]: cannot assign `y` in match guard
--> $DIR/match-guards-partially-borrow.rs:246:13
--> $DIR/match-guards-partially-borrow.rs:244:13
|
LL | match *y {
| -- value is immutable in match guard
@@ -102,7 +102,7 @@ LL | y = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `y` in match guard
--> $DIR/match-guards-partially-borrow.rs:257:13
--> $DIR/match-guards-partially-borrow.rs:255:13
|
LL | match *y {
| -- value is immutable in match guard
@@ -111,7 +111,7 @@ LL | y = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `z` in match guard
--> $DIR/match-guards-partially-borrow.rs:268:13
--> $DIR/match-guards-partially-borrow.rs:266:13
|
LL | match z {
| - value is immutable in match guard
@@ -120,7 +120,7 @@ LL | z = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `z` in match guard
--> $DIR/match-guards-partially-borrow.rs:279:13
--> $DIR/match-guards-partially-borrow.rs:277:13
|
LL | match z {
| - value is immutable in match guard
@@ -129,7 +129,7 @@ LL | z = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `a` in match guard
--> $DIR/match-guards-partially-borrow.rs:291:13
--> $DIR/match-guards-partially-borrow.rs:289:13
|
LL | match a {
| - value is immutable in match guard
@@ -138,7 +138,7 @@ LL | a = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `a` in match guard
--> $DIR/match-guards-partially-borrow.rs:303:13
--> $DIR/match-guards-partially-borrow.rs:301:13
|
LL | match a {
| - value is immutable in match guard
@@ -147,7 +147,7 @@ LL | a = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `b` in match guard
--> $DIR/match-guards-partially-borrow.rs:314:13
--> $DIR/match-guards-partially-borrow.rs:312:13
|
LL | match b {
| - value is immutable in match guard
@@ -156,7 +156,7 @@ LL | b = &true;
| ^^^^^^^^^ cannot assign
error[E0510]: cannot assign `b` in match guard
--> $DIR/match-guards-partially-borrow.rs:325:13
--> $DIR/match-guards-partially-borrow.rs:323:13
|
LL | match b {
| - value is immutable in match guard
@@ -3,8 +3,6 @@
// Unlike `if` condition, `match` guards accept struct literals.
// This is detected in <https://github.com/rust-lang/rust/pull/74566#issuecomment-663613705>.
#![feature(if_let_guard)]
#[derive(PartialEq)]
struct Foo {
x: isize,
@@ -1,7 +1,5 @@
//@ edition: 2024
#![feature(if_let_guard)]
fn main() {
let mut x = Some(String::new());
let ref mut y @ ref mut z = x;
@@ -1,5 +1,5 @@
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:7:9
--> $DIR/conflicting_bindings.rs:5:9
|
LL | let ref mut y @ ref mut z = x;
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -7,7 +7,7 @@ LL | let ref mut y @ ref mut z = x;
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:9:14
--> $DIR/conflicting_bindings.rs:7:14
|
LL | let Some(ref mut y @ ref mut z) = x else { return };
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -15,7 +15,7 @@ LL | let Some(ref mut y @ ref mut z) = x else { return };
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:11:17
--> $DIR/conflicting_bindings.rs:9:17
|
LL | if let Some(ref mut y @ ref mut z) = x {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -23,7 +23,7 @@ LL | if let Some(ref mut y @ ref mut z) = x {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:13:17
--> $DIR/conflicting_bindings.rs:11:17
|
LL | if let Some(ref mut y @ ref mut z) = x && true {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -31,7 +31,7 @@ LL | if let Some(ref mut y @ ref mut z) = x && true {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:15:43
--> $DIR/conflicting_bindings.rs:13:43
|
LL | if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && true {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -39,7 +39,7 @@ LL | if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && tru
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:17:20
--> $DIR/conflicting_bindings.rs:15:20
|
LL | while let Some(ref mut y @ ref mut z) = x {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -47,7 +47,7 @@ LL | while let Some(ref mut y @ ref mut z) = x {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:19:20
--> $DIR/conflicting_bindings.rs:17:20
|
LL | while let Some(ref mut y @ ref mut z) = x && true {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -55,7 +55,7 @@ LL | while let Some(ref mut y @ ref mut z) = x && true {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:22:9
--> $DIR/conflicting_bindings.rs:20:9
|
LL | ref mut y @ ref mut z => {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -63,7 +63,7 @@ LL | ref mut y @ ref mut z => {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:25:24
--> $DIR/conflicting_bindings.rs:23:24
|
LL | () if let Some(ref mut y @ ref mut z) = x => {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
#![deny(irrefutable_let_patterns)]
fn main() {
@@ -1,5 +1,5 @@
error: irrefutable `if let` pattern
--> $DIR/deny-irrefutable-let-patterns.rs:6:8
--> $DIR/deny-irrefutable-let-patterns.rs:4:8
|
LL | if let _ = 5 {}
| ^^^^^^^^^
@@ -7,13 +7,13 @@ LL | if let _ = 5 {}
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
note: the lint level is defined here
--> $DIR/deny-irrefutable-let-patterns.rs:3:9
--> $DIR/deny-irrefutable-let-patterns.rs:1:9
|
LL | #![deny(irrefutable_let_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: irrefutable `while let` pattern
--> $DIR/deny-irrefutable-let-patterns.rs:8:11
--> $DIR/deny-irrefutable-let-patterns.rs:6:11
|
LL | while let _ = 5 {
| ^^^^^^^^^
@@ -22,7 +22,7 @@ LL | while let _ = 5 {
= help: consider instead using a `loop { ... }` with a `let` inside it
error: irrefutable `if let` guard pattern
--> $DIR/deny-irrefutable-let-patterns.rs:13:14
--> $DIR/deny-irrefutable-let-patterns.rs:11:14
|
LL | _ if let _ = 2 => {}
| ^^^^^^^^^
+1 -1
View File
@@ -1,7 +1,7 @@
//@ revisions: pin_ergonomics normal
//@ edition:2024
#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))]
#![feature(if_let_guard, negative_impls)]
#![feature(negative_impls)]
#![allow(incomplete_features)]
use std::pin::Pin;
@@ -5,7 +5,6 @@
#![allow(path_statements)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
#![feature(if_let_guard)]
fn id(x: bool) -> bool {
x
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
enum VecWrapper { A(Vec<i32>) }
fn if_guard(x: VecWrapper) -> usize {
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `v` in pattern guard
--> $DIR/rfc-reject-double-move-across-arms.rs:7:36
--> $DIR/rfc-reject-double-move-across-arms.rs:5:36
|
LL | VecWrapper::A(v) if { drop(v); false } => 1,
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
@@ -11,7 +11,7 @@ LL | VecWrapper::A(v) if { drop(v.clone()); false } => 1,
| ++++++++
error[E0507]: cannot move out of `v` in pattern guard
--> $DIR/rfc-reject-double-move-across-arms.rs:15:51
--> $DIR/rfc-reject-double-move-across-arms.rs:13:51
|
LL | VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1,
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
@@ -1,5 +1,3 @@
#![feature(if_let_guard)]
struct A { a: Box<i32> }
fn if_guard(n: i32) {
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `v` in pattern guard
--> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30
--> $DIR/rfc-reject-double-move-in-first-arm.rs:6:30
|
LL | A { a: v } if { drop(v); true } => v,
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait
@@ -11,7 +11,7 @@ LL | A { a: v } if { drop(v.clone()); true } => v,
| ++++++++
error[E0507]: cannot move out of `v` in pattern guard
--> $DIR/rfc-reject-double-move-in-first-arm.rs:17:45
--> $DIR/rfc-reject-double-move-in-first-arm.rs:15:45
|
LL | A { a: v } if let Some(()) = { drop(v); Some(()) } => v,
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait

Some files were not shown because too many files have changed in this diff Show More