diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8cc4c18c02abf..a30a797beffaa 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -718,7 +718,8 @@ impl Features { /// Some features are not allowed to be used together at the same time, if /// the two are present, produce an error. -/// -/// Currently empty, but we will probably need this again in the future, -/// so let's keep it in for now. -pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[]; +pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[ + // Experimental match ergonomics rulesets are incompatible with each other, to simplify the + // boolean logic required to tell which typing rules to use. + (sym::ref_pat_eat_one_layer_2024, sym::ref_pat_eat_one_layer_2024_structural), +]; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4870e6193c3f1..1913bc0e741cd 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -21,6 +21,7 @@ use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; +use rustc_span::edition::Edition; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::Spanned; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; @@ -168,15 +169,16 @@ enum AdjustMode { Pass, } -/// `ref mut` patterns (explicit or match-ergonomics) -/// are not allowed behind an `&` reference. +/// `ref mut` bindings (explicit or match-ergonomics) are not allowed behind an `&` reference. +/// Normally, the borrow checker enforces this, but for (currently experimental) match ergonomics, +/// we track this when typing patterns for two purposes: /// -/// This includes explicit `ref mut` behind `&` patterns -/// that match against `&mut` references, -/// where the code would have compiled -/// had the pattern been written as `&mut`. -/// However, the borrow checker will not catch -/// this last case, so we need to throw an error ourselves. +/// - For RFC 3627's Rule 3, when this would prevent us from binding with `ref mut`, we limit the +/// default binding mode to be by shared `ref` when it would otherwise be `ref mut`. +/// +/// - For RFC 3627's Rule 5, we allow `&` patterns to match against `&mut` references, treating them +/// as if they were shared references. Since the scrutinee is mutable in this case, the borrow +/// checker won't catch if we bind with `ref mut`, so we need to throw an error ourselves. #[derive(Clone, Copy, Debug, PartialEq, Eq)] enum MutblCap { /// Mutability restricted to immutable. @@ -212,7 +214,67 @@ impl MutblCap { } } +/// Variations on RFC 3627's Rule 4: when do reference patterns match against inherited references? +/// +/// "Inherited reference" designates the `&`/`&mut` types that arise from using match ergonomics, i.e. +/// from matching a reference type with a non-reference pattern. E.g. when `Some(x)` matches on +/// `&mut Option<&T>`, `x` gets type `&mut &T` and the outer `&mut` is considered "inherited". +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum InheritedRefMatchRule { + /// Reference patterns consume only the inherited reference if possible, regardless of whether + /// the underlying type being matched against is a reference type. If there is no inherited + /// reference, a reference will be consumed from the underlying type. + EatOuter, + /// Reference patterns consume only a reference from the underlying type if possible. If the + /// underlying type is not a reference type, the inherited reference will be consumed. + EatInner, + /// When the underlying type is a reference type, reference patterns consume both layers of + /// reference, i.e. they both reset the binding mode and consume the reference type. Reference + /// patterns are not permitted when there is no underlying reference type, i.e. they can't eat + /// only an inherited reference. This is the current stable Rust behavior. + EatBoth, +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + /// Experimental pattern feature: after matching against a shared reference, do we limit the + /// default binding mode in subpatterns to be `ref` when it would otherwise be `ref mut`? + /// This corresponds to Rule 3 of RFC 3627. + fn downgrade_mut_inside_shared(&self) -> bool { + // NB: RFC 3627 proposes stabilizing Rule 3 in all editions. If we adopt the same behavior + // across all editions, this may be removed. + self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural() + } + + /// Experimental pattern feature: when do reference patterns match against inherited references? + /// This corresponds to variations on Rule 4 of RFC 3627. + fn ref_pat_matches_inherited_ref(&self, edition: Edition) -> InheritedRefMatchRule { + // NB: The particular rule used here is likely to differ across editions, so calls to this + // may need to become edition checks after match ergonomics stabilize. + if edition.at_least_rust_2024() { + if self.tcx.features().ref_pat_eat_one_layer_2024() { + InheritedRefMatchRule::EatOuter + } else if self.tcx.features().ref_pat_eat_one_layer_2024_structural() { + InheritedRefMatchRule::EatInner + } else { + // Currently, matching against an inherited ref on edition 2024 is an error. + // Use `EatBoth` as a fallback to be similar to stable Rust. + InheritedRefMatchRule::EatBoth + } + } else { + InheritedRefMatchRule::EatBoth + } + } + + /// Experimental pattern feature: do `&` patterns match against `&mut` references, treating them + /// as if they were shared references? This corresponds to Rule 5 of RFC 3627. + fn ref_pat_matches_mut_ref(&self) -> bool { + // NB: RFC 3627 proposes stabilizing Rule 5 in all editions. If we adopt the same behavior + // across all editions, this may be removed. + self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural() + } + /// Type check the given top level pattern against the `expected` type. /// /// If a `Some(span)` is provided and `origin_expr` holds, @@ -473,13 +535,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } - let features = self.tcx.features(); - if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural() - { + if self.downgrade_mut_inside_shared() { def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl()); - if def_br == ByRef::Yes(Mutability::Not) { - max_ref_mutbl = MutblCap::Not; - } + } + if def_br == ByRef::Yes(Mutability::Not) { + max_ref_mutbl = MutblCap::Not; } if !pat_adjustments.is_empty() { @@ -707,6 +767,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine the binding mode... let bm = match user_bind_annot { BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => { + // Only mention the experimental `mut_ref` feature if if we're in edition 2024 and + // using other experimental matching features compatible with it. if pat.span.at_least_rust_2024() && (self.tcx.features().ref_pat_eat_one_layer_2024() || self.tcx.features().ref_pat_eat_one_layer_2024_structural()) @@ -2204,55 +2266,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut pat_info: PatInfo<'_, 'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let features = tcx.features(); - let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024(); - let ref_pat_eat_one_layer_2024_structural = - features.ref_pat_eat_one_layer_2024_structural(); - - let no_ref_mut_behind_and = - ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural; - let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and; let pat_prefix_span = inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)); - if no_ref_mut_behind_and { - if pat_mutbl == Mutability::Not { - // Prevent the inner pattern from binding with `ref mut`. - pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span); - } - } else { - pat_info.max_ref_mutbl = MutblCap::Mut; + let ref_pat_matches_mut_ref = self.ref_pat_matches_mut_ref(); + if ref_pat_matches_mut_ref && pat_mutbl == Mutability::Not { + // If `&` patterns can match against mutable reference types (RFC 3627, Rule 5), we need + // to prevent subpatterns from binding with `ref mut`. Subpatterns of a shared reference + // pattern should have read-only access to the scrutinee, and the borrow checker won't + // catch it in this case. + pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span); } expected = self.try_structurally_resolve_type(pat.span, expected); - if new_match_ergonomics { - if let ByRef::Yes(inh_mut) = pat_info.binding_mode { - if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() { - // Don't attempt to consume inherited reference - pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl); - } else { + // Determine whether we're consuming an inherited reference and resetting the default + // binding mode, based on edition and enabled experimental features. + if let ByRef::Yes(inh_mut) = pat_info.binding_mode { + match self.ref_pat_matches_inherited_ref(pat.span.edition()) { + InheritedRefMatchRule::EatOuter => { // ref pattern attempts to consume inherited reference if pat_mutbl > inh_mut { // Tried to match inherited `ref` with `&mut` - if !ref_pat_eat_one_layer_2024_structural { - let err_msg = "mismatched types"; - let err = if let Some(span) = pat_prefix_span { - let mut err = self.dcx().struct_span_err(span, err_msg); - err.code(E0308); - err.note("cannot match inherited `&` with `&mut` pattern"); - err.span_suggestion_verbose( - span, - "replace this `&mut` pattern with `&`", - "&", - Applicability::MachineApplicable, - ); - err - } else { - self.dcx().struct_span_err(pat.span, err_msg) - }; - err.emit(); + // NB: This assumes that `&` patterns can match against mutable references + // (RFC 3627, Rule 5). If we implement a pattern typing ruleset with Rule 4E + // but not Rule 5, we'll need to check that here. + debug_assert!(ref_pat_matches_mut_ref); + let err_msg = "mismatched types"; + let err = if let Some(span) = pat_prefix_span { + let mut err = self.dcx().struct_span_err(span, err_msg); + err.code(E0308); + err.note("cannot match inherited `&` with `&mut` pattern"); + err.span_suggestion_verbose( + span, + "replace this `&mut` pattern with `&`", + "&", + Applicability::MachineApplicable, + ); + err + } else { + self.dcx().struct_span_err(pat.span, err_msg) + }; + err.emit(); + } + pat_info.binding_mode = ByRef::No; + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } + InheritedRefMatchRule::EatInner => { + if let ty::Ref(_, _, r_mutbl) = *expected.kind() { + // Match against the reference type; don't consume the inherited ref. + pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl); + } else { + // The expected type isn't a reference, so match against the inherited ref. + if pat_mutbl > inh_mut { + // We can't match an inherited shared reference with `&mut`. This will + // be a type error later, since we're matching a reference pattern + // against a non-reference type. + // NB: This assumes that `&` patterns can match against mutable + // references (RFC 3627, Rule 5). If we implement a pattern typing + // ruleset with Rule 4 but not Rule 5, we'll need to check that here. + debug_assert!(ref_pat_matches_mut_ref); + } else { pat_info.binding_mode = ByRef::No; self.typeck_results .borrow_mut() @@ -2261,24 +2338,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_pat(inner, expected, pat_info); return expected; } - } else { - pat_info.binding_mode = ByRef::No; - self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); - self.check_pat(inner, expected, pat_info); - return expected; } } - } - } else { - // Reset binding mode on old editions - if pat_info.binding_mode != ByRef::No { - pat_info.binding_mode = ByRef::No; - self.add_rust_2024_migration_desugared_pat( - pat_info.top_info.hir_id, - pat.span, - inner.span, - "cannot implicitly match against multiple layers of reference", - ) + InheritedRefMatchRule::EatBoth => { + // Reset binding mode on old editions + pat_info.binding_mode = ByRef::No; + self.add_rust_2024_migration_desugared_pat( + pat_info.top_info.hir_id, + pat.span, + inner.span, + "cannot implicitly match against multiple layers of reference", + ) + } } } @@ -2293,10 +2364,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("check_pat_ref: expected={:?}", expected); match *expected.kind() { ty::Ref(_, r_ty, r_mutbl) - if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl) + if (ref_pat_matches_mut_ref && r_mutbl >= pat_mutbl) || r_mutbl == pat_mutbl => { - if no_ref_mut_behind_and && r_mutbl == Mutability::Not { + if r_mutbl == Mutability::Not { pat_info.max_ref_mutbl = MutblCap::Not; } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr deleted file mode 100644 index f8672d755b959..0000000000000 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr +++ /dev/null @@ -1,169 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 - | -LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { - | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | types differ in mutability - | - = note: expected reference `&Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 - | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 - | -LL | let _: &mut u32 = x; - | -------- ^ types differ in mutability - | | - | expected due to this - | - = note: expected mutable reference `&mut u32` - found reference `&{integer}` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 - | -LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 - | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` - | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` - | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 - | -LL | let &mut _ = &&0; - | ^^^^^^ --- this expression has type `&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; - | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 - | -LL | let &mut _ = &&mut 0; - | ^^^^^^ ------- this expression has type `&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; - | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 - | -LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; - | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&mut &&&mut &mut {integer}` - found mutable reference `&mut _` - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 - | -LL | let &_ = generic(); - | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` - | - = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` -note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 - | -LL | fn generic() -> R { - | ^^^ required by this bound in `generic` - -error: aborting due to 15 previous errors - -Some errors have detailed explanations: E0277, E0308, E0658. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr deleted file mode 100644 index a37316b3097b0..0000000000000 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr +++ /dev/null @@ -1,199 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 - | -LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(&_)) = &Some(&Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 - | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 - | -LL | let _: &mut u32 = x; - | -------- ^ types differ in mutability - | | - | expected due to this - | - = note: expected mutable reference `&mut u32` - found reference `&{integer}` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 - | -LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 - | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 - | -LL | let &mut _ = &&0; - | ^^^^^^ --- this expression has type `&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; - | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:37:17 - | -LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:41:22 - | -LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 - | -LL | let &mut _ = &&mut 0; - | ^^^^^^ ------- this expression has type `&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; - | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 - | -LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; - | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&mut &&&mut &mut {integer}` - found mutable reference `&mut _` - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 - | -LL | let &_ = generic(); - | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` - | - = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` -note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 - | -LL | fn generic() -> R { - | ^^^ required by this bound in `generic` - -error: aborting due to 17 previous errors - -Some errors have detailed explanations: E0277, E0308, E0658. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs deleted file mode 100644 index fd616807b285c..0000000000000 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ /dev/null @@ -1,83 +0,0 @@ -//@ edition: 2024 -//@ revisions: classic structural both -#![allow(incomplete_features)] -#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] - -pub fn main() { - if let Some(&mut Some(&_)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - } - if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //~^ ERROR: mismatched types - } - if let Some(&Some(x)) = &mut Some(&Some(0)) { - let _: &mut u32 = x; - //~^ ERROR: mismatched types - } - if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - //~^ ERROR: mismatched types - } - if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - //~^ ERROR: mismatched types - } - if let Some(&mut Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - } - if let Some(&mut Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - } - - let &mut _ = &&0; - //~^ ERROR: mismatched types - - let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; - //~^ ERROR: mismatched types - - if let Some(&mut Some(&_)) = &Some(&mut Some(0)) { - //[classic]~^ ERROR: mismatched types - } - - if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { - //[classic]~^ ERROR: mismatched types - } - - let &mut _ = &&mut 0; - //~^ ERROR: mismatched types - - let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; - //~^ ERROR: mismatched types - - let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; - //~^ ERROR: mismatched types - - if let Some(&mut _) = &mut Some(&0) { - //[structural]~^ ERROR - } - - struct Foo(u8); - - let Foo(mut a) = &Foo(0); - //~^ ERROR: binding cannot be both mutable and by-reference - a = &42; - - let Foo(mut a) = &mut Foo(0); - //~^ ERROR: binding cannot be both mutable and by-reference - a = &mut 42; - - fn generic() -> R { - R::meow() - } - - trait Ref: Sized { - fn meow() -> Self; - } - - impl Ref for &'static mut [(); 0] { - fn meow() -> Self { - &mut [] - } - } - - let &_ = generic(); //~ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277] -} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr deleted file mode 100644 index 2f62e9974fa3f..0000000000000 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr +++ /dev/null @@ -1,180 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17 - | -LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { - | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | types differ in mutability - | - = note: expected reference `&Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23 - | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27 - | -LL | let _: &mut u32 = x; - | -------- ^ types differ in mutability - | | - | expected due to this - | - = note: expected mutable reference `&mut u32` - found reference `&{integer}` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23 - | -LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29 - | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` - | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` - | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 - | -LL | let &mut _ = &&0; - | ^^^^^^ --- this expression has type `&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; - | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9 - | -LL | let &mut _ = &&mut 0; - | ^^^^^^ ------- this expression has type `&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9 - | -LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; - | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14 - | -LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; - | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` - | | - | types differ in mutability - | - = note: expected reference `&&&&mut &&&mut &mut {integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:54:17 - | -LL | if let Some(&mut _) = &mut Some(&0) { - | ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^ - | - = note: see issue #123076 for more information - = help: add `#![feature(mut_ref)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0277]: the trait bound `&_: main::Ref` is not satisfied - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14 - | -LL | let &_ = generic(); - | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` - | - = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` -note: required by a bound in `generic` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19 - | -LL | fn generic() -> R { - | ^^^ required by this bound in `generic` - -error: aborting due to 16 previous errors - -Some errors have detailed explanations: E0277, E0308, E0658. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/pattern/no_ref_mut_behind_and.rs b/tests/ui/pattern/no_ref_mut_behind_and.rs deleted file mode 100644 index c18d64904d035..0000000000000 --- a/tests/ui/pattern/no_ref_mut_behind_and.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ edition: 2021 -//@ run-pass -#![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] - -fn main() { - let &[[x]] = &[&mut [42]]; - let _: &i32 = x; -} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr similarity index 88% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr index a8b813941109c..c62461140750b 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:6:29 + --> $DIR/borrowck-errors.rs:9:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:11:10 + --> $DIR/borrowck-errors.rs:14:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs similarity index 54% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index 79403b1936528..a01e9ca265760 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs @@ -1,6 +1,9 @@ //@ edition: 2024 +//@ revisions: classic structural +//! Tests for pattern errors not handled by the pattern typing rules, but by borrowck. #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&Some(x)) = Some(&Some(&mut 0)) { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr new file mode 100644 index 0000000000000..c62461140750b --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr @@ -0,0 +1,25 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:9:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - if let Some(&Some(x)) = Some(&Some(&mut 0)) { +LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:14:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr new file mode 100644 index 0000000000000..89a52ba7d1ddb --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr @@ -0,0 +1,58 @@ +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:9:9 + | +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:12:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:15:9 + | +LL | let &mut _ = &&mut 0; + | ^^^^^^ ------- this expression has type `&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:18:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:21:14 + | +LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; + | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&mut &&&mut &mut {integer}` + found mutable reference `&mut _` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs new file mode 100644 index 0000000000000..e22bd1f8f6c99 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs @@ -0,0 +1,23 @@ +//@ edition: 2024 +//@ revisions: classic structural +//! Test that `&mut` patterns don't match shared reference types under new typing rules in Rust 2024 +#![allow(incomplete_features)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] + +pub fn main() { + let &mut _ = &&0; + //~^ ERROR: mismatched types + + let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + //~^ ERROR: mismatched types + + let &mut _ = &&mut 0; + //~^ ERROR: mismatched types + + let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + //~^ ERROR: mismatched types + + let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr new file mode 100644 index 0000000000000..89a52ba7d1ddb --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr @@ -0,0 +1,58 @@ +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:9:9 + | +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:12:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:15:9 + | +LL | let &mut _ = &&mut 0; + | ^^^^^^ ------- this expression has type `&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:18:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/cannot-mutably-deref-shared-ref.rs:21:14 + | +LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; + | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&mut &&&mut &mut {integer}` + found mutable reference `&mut _` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.rs similarity index 100% rename from tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.rs diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.stderr similarity index 100% rename from tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/feature-gate-ref_pat_eat_one_layer_2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr new file mode 100644 index 0000000000000..43560a1803026 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr @@ -0,0 +1,23 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mut-ref-mut.rs:11:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mut-ref-mut.rs:15:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs new file mode 100644 index 0000000000000..786587984ba41 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 +//@ revisions: classic structural +//! Test diagnostics for binding with `mut` when the default binding mode is by-ref. +#![allow(incomplete_features)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] + +pub fn main() { + struct Foo(u8); + + let Foo(mut a) = &Foo(0); + //~^ ERROR: binding cannot be both mutable and by-reference + a = &42; + + let Foo(mut a) = &mut Foo(0); + //~^ ERROR: binding cannot be both mutable and by-reference + a = &mut 42; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr new file mode 100644 index 0000000000000..43560a1803026 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr @@ -0,0 +1,23 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mut-ref-mut.rs:11:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mut-ref-mut.rs:15:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr new file mode 100644 index 0000000000000..2bc3ecb7636d0 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -0,0 +1,111 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:15:17 + | +LL | if let Some(&mut x) = &Some(&mut 0) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&x) = &Some(&mut 0) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:19:17 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:23:22 + | +LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:28:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&_)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:31:23 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:34:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:37:29 + | +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:40:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:43:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ~ + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs new file mode 100644 index 0000000000000..3535ba9c7019a --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs @@ -0,0 +1,46 @@ +//@ edition: 2024 +//@ revisions: classic structural +//! Test cases for poorly-typed patterns in edition 2024 which are caught by HIR typeck. These must +//! be separate from cases caught by MIR borrowck or the latter errors may not be emitted. +#![allow(incomplete_features)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] + +pub fn main() { + if let Some(&mut x) = &mut Some(&0) { + //[structural]~^ ERROR: mismatched types + let _: &u32 = x; + } + + if let Some(&mut x) = &Some(&mut 0) { + //[classic]~^ ERROR: mismatched types + let _: &u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //[classic]~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { + //[classic]~^ ERROR: mismatched types + let _: &u32 = x; + } + + if let Some(&mut Some(&_)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + //~^ ERROR: mismatched types + } + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr new file mode 100644 index 0000000000000..59d65553fae8f --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr @@ -0,0 +1,89 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:10:17 + | +LL | if let Some(&mut x) = &mut Some(&0) { + | ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:10:17 + | +LL | if let Some(&mut x) = &mut Some(&0) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(x) = &mut Some(&0) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:28:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:31:23 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:34:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:37:29 + | +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:40:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:43:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed similarity index 73% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed index e69d169966b52..4f4941975d804 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed @@ -1,7 +1,11 @@ //@ edition: 2024 //@ run-rustfix +//@ revisions: classic structural +//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts +//! to bind by mutable reference. #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr similarity index 79% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr index 8e135b65253fd..6c384a51fac14 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:7:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:12:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:20:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:24:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs similarity index 73% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index a300cbcd4df52..b29bff7603f7a 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs @@ -1,7 +1,11 @@ //@ edition: 2024 //@ run-rustfix +//@ revisions: classic structural +//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts +//! to bind by mutable reference. #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed new file mode 100644 index 0000000000000..4f4941975d804 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed @@ -0,0 +1,33 @@ +//@ edition: 2024 +//@ run-rustfix +//@ revisions: classic structural +//! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts +//! to bind by mutable reference. +#![allow(incomplete_features)] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] + +pub fn main() { + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &mut pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + + let &mut (ref mut a, ref mut b) = &mut (true, false); + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //~| ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut bool = a; + let _: &mut bool = b; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr new file mode 100644 index 0000000000000..6c384a51fac14 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr @@ -0,0 +1,43 @@ +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:24:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:28:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs similarity index 54% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs index afea249ffef0b..9372049a2b283 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs @@ -1,9 +1,9 @@ //@ run-pass //@ edition: 2021 -//@ revisions: classic structural both +//@ revisions: classic structural #![allow(incomplete_features)] -#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let &Some(Some(x)) = &Some(&mut Some(0)) { diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs similarity index 100% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr similarity index 100% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs new file mode 100644 index 0000000000000..cb8fdb489c028 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.rs @@ -0,0 +1,30 @@ +//@ edition: 2024 +//@ revisions: with_impl without_impl +//@[with_impl] run-pass +//! Sanity check that experimental new pattern typing rules work as expected with trait selection + +fn main() { + fn generic() -> (R, bool) { + R::meow() + } + + trait Ref: Sized { + fn meow() -> (Self, bool); + } + + #[cfg(with_impl)] + impl Ref for &'static [(); 0] { + fn meow() -> (Self, bool) { + (&[], false) + } + } + + impl Ref for &'static mut [(); 0] { + fn meow() -> (Self, bool) { + (&mut [], true) + } + } + + let (&_, b) = generic(); //[without_impl]~ ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277] + assert!(!b); +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr new file mode 100644 index 0000000000000..83e45221facc7 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/trait-selection-sanity.without_impl.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `&_: main::Ref` is not satisfied + --> $DIR/trait-selection-sanity.rs:28:19 + | +LL | let (&_, b) = generic(); + | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` + | + = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` +note: required by a bound in `generic` + --> $DIR/trait-selection-sanity.rs:7:19 + | +LL | fn generic() -> (R, bool) { + | ^^^ required by this bound in `generic` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs similarity index 62% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index b145446de0a1c..077b52d8f274e 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -1,9 +1,11 @@ -//@ run-pass //@ edition: 2024 -//@ revisions: classic structural both +//@ revisions: classic structural +//@ run-pass +//! Test cases for well-typed patterns in edition 2024. These are in their own file to ensure we +//! pass both HIR typeck and MIR borrowck, as we may skip the latter if grouped with failing tests. #![allow(incomplete_features)] -#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(Some(&x)) = &Some(&Some(0)) { @@ -54,35 +56,4 @@ pub fn main() { if let Some(&Some(x)) = &mut Some(Some(0)) { let _: u32 = x; } - #[cfg(any(classic, both))] - if let Some(&mut x) = &mut Some(&0) { - let _: &u32 = x; - } - #[cfg(any(structural, both))] - if let Some(&mut x) = &Some(&mut 0) { - let _: &u32 = x; - } - - fn generic() -> (R, bool) { - R::meow() - } - - trait Ref: Sized { - fn meow() -> (Self, bool); - } - - impl Ref for &'static [(); 0] { - fn meow() -> (Self, bool) { - (&[], false) - } - } - - impl Ref for &'static mut [(); 0] { - fn meow() -> (Self, bool) { - (&mut [], true) - } - } - - let (&_, b) = generic(); - assert!(!b); }