Rollup merge of #123512 - Jules-Bertholet:ref-pat-eat-one-layer-2024, r=Nadrieril
Match ergonomics 2024: Implement eat-one-layer r? `@Nadrieril` cc #123076 `@rustbot` label A-edition-2024 A-patterns
This commit is contained in:
commit
239b3728d5
14 changed files with 680 additions and 77 deletions
|
@ -36,6 +36,7 @@ use rustc_macros::HashStable_Generic;
|
||||||
use rustc_span::source_map::{respan, Spanned};
|
use rustc_span::source_map::{respan, Spanned};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||||
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use thin_vec::{thin_vec, ThinVec};
|
use thin_vec::{thin_vec, ThinVec};
|
||||||
|
@ -731,6 +732,13 @@ impl BindingAnnotation {
|
||||||
Self::MUT_REF_MUT => "mut ref mut ",
|
Self::MUT_REF_MUT => "mut ref mut ",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
|
||||||
|
if let ByRef::Yes(old_mutbl) = &mut self.0 {
|
||||||
|
*old_mutbl = cmp::min(*old_mutbl, mutbl);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
|
|
@ -575,6 +575,8 @@ declare_features! (
|
||||||
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
||||||
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
||||||
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
||||||
|
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
|
||||||
|
(incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
|
||||||
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
||||||
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
|
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
|
||||||
/// Allows using the `#[register_tool]` attribute.
|
/// Allows using the `#[register_tool]` attribute.
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct TopInfo<'tcx> {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct PatInfo<'tcx, 'a> {
|
struct PatInfo<'tcx, 'a> {
|
||||||
binding_mode: BindingAnnotation,
|
binding_mode: BindingAnnotation,
|
||||||
|
max_ref_mutbl: Mutability,
|
||||||
top_info: TopInfo<'tcx>,
|
top_info: TopInfo<'tcx>,
|
||||||
decl_origin: Option<DeclOrigin<'a>>,
|
decl_origin: Option<DeclOrigin<'a>>,
|
||||||
|
|
||||||
|
@ -161,8 +162,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
decl_origin: Option<DeclOrigin<'tcx>>,
|
decl_origin: Option<DeclOrigin<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let info = TopInfo { expected, origin_expr, span };
|
let info = TopInfo { expected, origin_expr, span };
|
||||||
let pat_info =
|
let pat_info = PatInfo {
|
||||||
PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin, current_depth: 0 };
|
binding_mode: INITIAL_BM,
|
||||||
|
max_ref_mutbl: Mutability::Mut,
|
||||||
|
top_info: info,
|
||||||
|
decl_origin,
|
||||||
|
current_depth: 0,
|
||||||
|
};
|
||||||
self.check_pat(pat, expected, pat_info);
|
self.check_pat(pat, expected, pat_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +179,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
/// Conversely, inside this module, `check_pat_top` should never be used.
|
/// Conversely, inside this module, `check_pat_top` should never be used.
|
||||||
#[instrument(level = "debug", skip(self, pat_info))]
|
#[instrument(level = "debug", skip(self, pat_info))]
|
||||||
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
|
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, current_depth, .. } = pat_info;
|
let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } =
|
||||||
|
pat_info;
|
||||||
|
|
||||||
let path_res = match &pat.kind {
|
let path_res = match &pat.kind {
|
||||||
PatKind::Path(qpath) => Some(
|
PatKind::Path(qpath) => Some(
|
||||||
|
@ -182,10 +189,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
|
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
|
||||||
let (expected, def_bm, ref_pattern_already_consumed) =
|
let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) =
|
||||||
self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
|
self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl);
|
||||||
let pat_info = PatInfo {
|
let pat_info = PatInfo {
|
||||||
binding_mode: def_bm,
|
binding_mode: def_bm,
|
||||||
|
max_ref_mutbl,
|
||||||
top_info: ti,
|
top_info: ti,
|
||||||
decl_origin: pat_info.decl_origin,
|
decl_origin: pat_info.decl_origin,
|
||||||
current_depth: current_depth + 1,
|
current_depth: current_depth + 1,
|
||||||
|
@ -290,16 +298,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
def_bm: BindingAnnotation,
|
def_bm: BindingAnnotation,
|
||||||
adjust_mode: AdjustMode,
|
adjust_mode: AdjustMode,
|
||||||
) -> (Ty<'tcx>, BindingAnnotation, bool) {
|
max_ref_mutbl: Mutability,
|
||||||
|
) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) {
|
||||||
|
if let ByRef::Yes(mutbl) = def_bm.0 {
|
||||||
|
debug_assert!(mutbl <= max_ref_mutbl);
|
||||||
|
}
|
||||||
match adjust_mode {
|
match adjust_mode {
|
||||||
AdjustMode::Pass => (expected, def_bm, false),
|
AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false),
|
||||||
AdjustMode::Reset => (expected, INITIAL_BM, false),
|
AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false),
|
||||||
AdjustMode::ResetAndConsumeRef(mutbl) => {
|
AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => {
|
||||||
(expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl))
|
let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl);
|
||||||
|
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||||
|
if mutbls_match {
|
||||||
|
debug!("consuming inherited reference");
|
||||||
|
(expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true)
|
||||||
|
} else {
|
||||||
|
let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut {
|
||||||
|
self.peel_off_references(
|
||||||
|
pat,
|
||||||
|
expected,
|
||||||
|
def_bm,
|
||||||
|
Mutability::Not,
|
||||||
|
max_ref_mutbl,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not)
|
||||||
|
};
|
||||||
|
(new_ty, new_bm, max_ref_mutbl, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(expected, INITIAL_BM, max_ref_mutbl, mutbls_match)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AdjustMode::Peel => {
|
AdjustMode::Peel => {
|
||||||
let peeled = self.peel_off_references(pat, expected, def_bm);
|
let peeled =
|
||||||
(peeled.0, peeled.1, false)
|
self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl);
|
||||||
|
(peeled.0, peeled.1, peeled.2, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +414,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
pat: &'tcx Pat<'tcx>,
|
pat: &'tcx Pat<'tcx>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
mut def_bm: BindingAnnotation,
|
mut def_bm: BindingAnnotation,
|
||||||
) -> (Ty<'tcx>, BindingAnnotation) {
|
max_peelable_mutability: Mutability,
|
||||||
|
mut max_ref_mutability: Mutability,
|
||||||
|
) -> (Ty<'tcx>, BindingAnnotation, Mutability) {
|
||||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||||
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
||||||
|
@ -391,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// See the examples in `ui/match-defbm*.rs`.
|
// See the examples in `ui/match-defbm*.rs`.
|
||||||
let mut pat_adjustments = vec![];
|
let mut pat_adjustments = vec![];
|
||||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
|
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
|
||||||
|
&& inner_mutability <= max_peelable_mutability
|
||||||
|
{
|
||||||
debug!("inspecting {:?}", expected);
|
debug!("inspecting {:?}", expected);
|
||||||
|
|
||||||
debug!("current discriminant is Ref, inserting implicit deref");
|
debug!("current discriminant is Ref, inserting implicit deref");
|
||||||
|
@ -411,6 +449,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||||
|
def_bm = def_bm.cap_ref_mutability(max_ref_mutability);
|
||||||
|
if def_bm.0 == ByRef::Yes(Mutability::Not) {
|
||||||
|
max_ref_mutability = Mutability::Not;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !pat_adjustments.is_empty() {
|
if !pat_adjustments.is_empty() {
|
||||||
debug!("default binding mode is now {:?}", def_bm);
|
debug!("default binding mode is now {:?}", def_bm);
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
|
@ -419,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.insert(pat.hir_id, pat_adjustments);
|
.insert(pat.hir_id, pat_adjustments);
|
||||||
}
|
}
|
||||||
|
|
||||||
(expected, def_bm)
|
(expected, def_bm, max_ref_mutability)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat_lit(
|
fn check_pat_lit(
|
||||||
|
@ -1109,15 +1154,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth } = pat_info;
|
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let on_error = |e| {
|
let on_error = |e| {
|
||||||
for pat in subpats {
|
for pat in subpats {
|
||||||
self.check_pat(
|
self.check_pat(pat, Ty::new_error(tcx, e), pat_info);
|
||||||
pat,
|
|
||||||
Ty::new_error(tcx, e),
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let report_unexpected_res = |res: Res| {
|
let report_unexpected_res = |res: Res| {
|
||||||
|
@ -1162,7 +1202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
|
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
|
||||||
|
|
||||||
// Type-check the tuple struct pattern against the expected type.
|
// Type-check the tuple struct pattern against the expected type.
|
||||||
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
|
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info);
|
||||||
let had_err = if let Some(err) = diag {
|
let had_err = if let Some(err) = diag {
|
||||||
err.emit();
|
err.emit();
|
||||||
true
|
true
|
||||||
|
@ -1180,11 +1220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
||||||
let field = &variant.fields[FieldIdx::from_usize(i)];
|
let field = &variant.fields[FieldIdx::from_usize(i)];
|
||||||
let field_ty = self.field_ty(subpat.span, field, args);
|
let field_ty = self.field_ty(subpat.span, field, args);
|
||||||
self.check_pat(
|
self.check_pat(subpat, field_ty, pat_info);
|
||||||
subpat,
|
|
||||||
field_ty,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth },
|
|
||||||
);
|
|
||||||
|
|
||||||
self.tcx.check_stability(
|
self.tcx.check_stability(
|
||||||
variant.fields[FieldIdx::from_usize(i)].did,
|
variant.fields[FieldIdx::from_usize(i)].did,
|
||||||
|
@ -2071,61 +2107,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
consumed_inherited_ref: bool,
|
consumed_inherited_ref: bool,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
if consumed_inherited_ref
|
||||||
let expected = self.shallow_resolve(expected);
|
&& pat.span.at_least_rust_2024()
|
||||||
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
|
&& self.tcx.features().ref_pat_eat_one_layer_2024
|
||||||
Ok(()) => {
|
{
|
||||||
// `demand::subtype` would be good enough, but using `eqtype` turns
|
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||||
// out to be equally general. See (note_1) for details.
|
self.check_pat(inner, expected, pat_info);
|
||||||
|
expected
|
||||||
|
} else {
|
||||||
|
let tcx = self.tcx;
|
||||||
|
let expected = self.shallow_resolve(expected);
|
||||||
|
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
|
||||||
|
Ok(()) => {
|
||||||
|
// `demand::subtype` would be good enough, but using `eqtype` turns
|
||||||
|
// out to be equally general. See (note_1) for details.
|
||||||
|
|
||||||
// Take region, inner-type from expected type if we can,
|
// Take region, inner-type from expected type if we can,
|
||||||
// to avoid creating needless variables. This also helps with
|
// to avoid creating needless variables. This also helps with
|
||||||
// the bad interactions of the given hack detailed in (note_1).
|
// the bad interactions of the given hack detailed in (note_1).
|
||||||
debug!("check_pat_ref: expected={:?}", expected);
|
debug!("check_pat_ref: expected={:?}", expected);
|
||||||
match *expected.kind() {
|
match *expected.kind() {
|
||||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
||||||
_ => {
|
_ => {
|
||||||
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
|
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
|
||||||
// We already matched against a match-ergonmics inserted reference,
|
// We already matched against a match-ergonmics inserted reference,
|
||||||
// so we don't need to match against a reference from the original type.
|
// so we don't need to match against a reference from the original type.
|
||||||
// Save this infor for use in lowering later
|
// Save this infor for use in lowering later
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.skipped_ref_pats_mut()
|
.skipped_ref_pats_mut()
|
||||||
.insert(pat.hir_id);
|
.insert(pat.hir_id);
|
||||||
(expected, expected)
|
(expected, expected)
|
||||||
} else {
|
} else {
|
||||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||||
param_def_id: None,
|
param_def_id: None,
|
||||||
span: inner.span,
|
span: inner.span,
|
||||||
});
|
});
|
||||||
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
|
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
|
||||||
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
|
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
|
||||||
let err = self.demand_eqtype_pat_diag(
|
let err = self.demand_eqtype_pat_diag(
|
||||||
pat.span,
|
pat.span,
|
||||||
expected,
|
expected,
|
||||||
ref_ty,
|
ref_ty,
|
||||||
pat_info.top_info,
|
pat_info.top_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Look for a case like `fn foo(&foo: u32)` and suggest
|
// Look for a case like `fn foo(&foo: u32)` and suggest
|
||||||
// `fn foo(foo: &u32)`
|
// `fn foo(foo: &u32)`
|
||||||
if let Some(mut err) = err {
|
if let Some(mut err) = err {
|
||||||
self.borrow_pat_suggestion(&mut err, pat);
|
self.borrow_pat_suggestion(&mut err, pat);
|
||||||
err.emit();
|
err.emit();
|
||||||
|
}
|
||||||
|
(ref_ty, inner_ty)
|
||||||
}
|
}
|
||||||
(ref_ty, inner_ty)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(guar) => {
|
||||||
Err(guar) => {
|
let err = Ty::new_error(tcx, guar);
|
||||||
let err = Ty::new_error(tcx, guar);
|
(err, err)
|
||||||
(err, err)
|
}
|
||||||
}
|
};
|
||||||
};
|
self.check_pat(inner, inner_ty, pat_info);
|
||||||
self.check_pat(inner, inner_ty, pat_info);
|
ref_ty
|
||||||
ref_ty
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a reference type with a fresh region variable.
|
/// Create a reference type with a fresh region variable.
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
hir::PatKind::Ref(inner, _)
|
hir::PatKind::Ref(inner, _)
|
||||||
if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
|
if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
|
||||||
{
|
{
|
||||||
self.lower_pattern_unadjusted(inner)
|
self.lower_pattern(inner)
|
||||||
}
|
}
|
||||||
_ => self.lower_pattern_unadjusted(pat),
|
_ => self.lower_pattern_unadjusted(pat),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1462,6 +1462,7 @@ symbols! {
|
||||||
receiver,
|
receiver,
|
||||||
recursion_limit,
|
recursion_limit,
|
||||||
reexport_test_harness_main,
|
reexport_test_harness_main,
|
||||||
|
ref_pat_eat_one_layer_2024,
|
||||||
ref_pat_everywhere,
|
ref_pat_everywhere,
|
||||||
ref_unwind_safe_trait,
|
ref_unwind_safe_trait,
|
||||||
reference,
|
reference,
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(Some(&0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
}
|
||||||
|
if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23
|
||||||
|
|
|
||||||
|
LL | let _: &u32 = x;
|
||||||
|
| ---- ^ expected `&u32`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let _: &u32 = &x;
|
||||||
|
| +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<Option<&{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
LL + if let Some(Some(&x)) = &Some(Some(&0)) {
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
|
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected `Option<{integer}>`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<{integer}>`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
note: to declare a mutable binding use: `mut x`
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider removing `&mut` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
| ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
note: to declare a mutable binding use: `mut x`
|
||||||
|
--> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider removing `&mut` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(x)) = &mut Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,37 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(ref_pat_eat_one_layer_2024)]
|
||||||
|
pub fn main() {
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(Some(&0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
}
|
||||||
|
if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:5:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:10:23
|
||||||
|
|
|
||||||
|
LL | let _: &u32 = x;
|
||||||
|
| ---- ^ expected `&u32`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let _: &u32 = &x;
|
||||||
|
| +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:13:23
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<Option<&{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL - if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
LL + if let Some(Some(&x)) = &Some(Some(&0)) {
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:17:17
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
|
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected `Option<{integer}>`, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<{integer}>`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
note: to declare a mutable binding use: `mut x`
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider removing `&mut` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:25:22
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:29:27
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
| ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
note: to declare a mutable binding use: `mut x`
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider removing `&mut` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(x)) = &mut Some(&Some(0)) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,65 @@
|
||||||
|
//@ run-pass
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(ref_pat_eat_one_layer_2024)]
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(Some(&0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&&x)) = &Some(Some(&0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&x)) = &mut Some(&Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(x)) = &mut Some(&Some(0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
if let &Some(Some(x)) = &Some(&mut Some(0)) {
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&x)) = &Some(&Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
let &mut x = &&mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
|
|
||||||
|
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
|
|
||||||
|
let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(ref_pat_eat_one_layer_2024)]
|
||||||
|
|
||||||
|
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(&_)) = Some(&Some(&mut 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let &mut _= &&0;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
|
||||||
|
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
|
||||||
|
|
|
||||||
|
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
||||||
|
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
| |
|
||||||
|
| 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:10: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:14: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:17:23
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) {
|
||||||
|
| ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>`
|
||||||
|
| |
|
||||||
|
| types differ in mutability
|
||||||
|
|
|
||||||
|
= note: expected mutable reference `&mut {integer}`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20: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:23:29
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
|
||||||
|
| ^^^^^^ ------------------------- this expression has type `&Option<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:28:9
|
||||||
|
|
|
||||||
|
LL | let &mut _= &&0;
|
||||||
|
| ^^^^^^ --- this expression has type `&&{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:31:9
|
||||||
|
|
|
||||||
|
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||||
|
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,11 @@
|
||||||
|
//@ edition: 2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(ref_pat_eat_one_layer_2024)]
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
if let Some(&Some(x)) = Some(&Some(&mut 0)) {
|
||||||
|
//~^ ERROR: cannot move out of a shared reference [E0507]
|
||||||
|
let _: &u32 = x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0507]: cannot move out of a shared reference
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:7: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 borrowing the pattern binding
|
||||||
|
|
|
||||||
|
LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0507`.
|
Loading…
Add table
Add a link
Reference in a new issue