1
Fork 0

Auto merge of #135755 - jieyouxu:rollup-rdwbhod, r=jieyouxu

Rollup of 5 pull requests

Successful merges:

 - #134276 (fully de-stabilize all custom inner attributes)
 - #135237 (Match Ergonomics 2024: document and reorganize the currently-implemented feature gates)
 - #135310 (Always force non-trimming of path in `unreachable_patterns` lint)
 - #135446 (further improve panic_immediate_abort by removing rtprintpanic! messages)
 - #135491 (Remove dead rustc_allowed_through_unstable_modules for std::os::fd contents)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-01-20 07:51:13 +00:00
commit ecda83b30f
45 changed files with 822 additions and 901 deletions

View file

@ -722,7 +722,8 @@ impl Features {
/// Some features are not allowed to be used together at the same time, if /// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error. /// the two are present, produce an error.
/// pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[
/// Currently empty, but we will probably need this again in the future, // Experimental match ergonomics rulesets are incompatible with each other, to simplify the
/// so let's keep it in for now. // boolean logic required to tell which typing rules to use.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[]; (sym::ref_pat_eat_one_layer_2024, sym::ref_pat_eat_one_layer_2024_structural),
];

View file

@ -21,6 +21,7 @@ use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
@ -169,15 +170,16 @@ enum AdjustMode {
Pass, Pass,
} }
/// `ref mut` patterns (explicit or match-ergonomics) /// `ref mut` bindings (explicit or match-ergonomics) are not allowed behind an `&` reference.
/// 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 /// - For RFC 3627's Rule 3, when this would prevent us from binding with `ref mut`, we limit the
/// that match against `&mut` references, /// default binding mode to be by shared `ref` when it would otherwise be `ref mut`.
/// where the code would have compiled ///
/// had the pattern been written as `&mut`. /// - For RFC 3627's Rule 5, we allow `&` patterns to match against `&mut` references, treating them
/// However, the borrow checker will not catch /// as if they were shared references. Since the scrutinee is mutable in this case, the borrow
/// this last case, so we need to throw an error ourselves. /// checker won't catch if we bind with `ref mut`, so we need to throw an error ourselves.
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum MutblCap { enum MutblCap {
/// Mutability restricted to immutable. /// Mutability restricted to immutable.
@ -213,7 +215,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> { 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. /// Type check the given top level pattern against the `expected` type.
/// ///
/// If a `Some(span)` is provided and `origin_expr` holds, /// If a `Some(span)` is provided and `origin_expr` holds,
@ -474,13 +536,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
} }
let features = self.tcx.features(); if self.downgrade_mut_inside_shared() {
if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural()
{
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl()); 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() { if !pat_adjustments.is_empty() {
@ -731,6 +791,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Determine the binding mode... // Determine the binding mode...
let bm = match user_bind_annot { let bm = match user_bind_annot {
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => { 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() 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()
|| self.tcx.features().ref_pat_eat_one_layer_2024_structural()) || self.tcx.features().ref_pat_eat_one_layer_2024_structural())
@ -2228,55 +2290,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
mut pat_info: PatInfo<'_, 'tcx>, mut pat_info: PatInfo<'_, 'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let tcx = self.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 = let pat_prefix_span =
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)); inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
if no_ref_mut_behind_and { let ref_pat_matches_mut_ref = self.ref_pat_matches_mut_ref();
if pat_mutbl == Mutability::Not { if ref_pat_matches_mut_ref && pat_mutbl == Mutability::Not {
// Prevent the inner pattern from binding with `ref mut`. // If `&` patterns can match against mutable reference types (RFC 3627, Rule 5), we need
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span); // 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
} else { // catch it in this case.
pat_info.max_ref_mutbl = MutblCap::Mut; 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); expected = self.try_structurally_resolve_type(pat.span, expected);
if new_match_ergonomics { // Determine whether we're consuming an inherited reference and resetting the default
if let ByRef::Yes(inh_mut) = pat_info.binding_mode { // binding mode, based on edition and enabled experimental features.
if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() { if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
// Don't attempt to consume inherited reference match self.ref_pat_matches_inherited_ref(pat.span.edition()) {
pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl); InheritedRefMatchRule::EatOuter => {
} else {
// ref pattern attempts to consume inherited reference // ref pattern attempts to consume inherited reference
if pat_mutbl > inh_mut { if pat_mutbl > inh_mut {
// Tried to match inherited `ref` with `&mut` // Tried to match inherited `ref` with `&mut`
if !ref_pat_eat_one_layer_2024_structural { // NB: This assumes that `&` patterns can match against mutable references
let err_msg = "mismatched types"; // (RFC 3627, Rule 5). If we implement a pattern typing ruleset with Rule 4E
let err = if let Some(span) = pat_prefix_span { // but not Rule 5, we'll need to check that here.
let mut err = self.dcx().struct_span_err(span, err_msg); debug_assert!(ref_pat_matches_mut_ref);
err.code(E0308); let err_msg = "mismatched types";
err.note("cannot match inherited `&` with `&mut` pattern"); let err = if let Some(span) = pat_prefix_span {
err.span_suggestion_verbose( let mut err = self.dcx().struct_span_err(span, err_msg);
span, err.code(E0308);
"replace this `&mut` pattern with `&`", err.note("cannot match inherited `&` with `&mut` pattern");
"&", err.span_suggestion_verbose(
Applicability::MachineApplicable, span,
); "replace this `&mut` pattern with `&`",
err "&",
} else { Applicability::MachineApplicable,
self.dcx().struct_span_err(pat.span, err_msg) );
}; err
err.emit(); } 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; pat_info.binding_mode = ByRef::No;
self.typeck_results self.typeck_results
.borrow_mut() .borrow_mut()
@ -2285,24 +2362,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.check_pat(inner, expected, pat_info); self.check_pat(inner, expected, pat_info);
return expected; 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;
} }
} }
} InheritedRefMatchRule::EatBoth => {
} else { // Reset binding mode on old editions
// Reset binding mode on old editions pat_info.binding_mode = ByRef::No;
if pat_info.binding_mode != ByRef::No { self.add_rust_2024_migration_desugared_pat(
pat_info.binding_mode = ByRef::No; pat_info.top_info.hir_id,
self.add_rust_2024_migration_desugared_pat( pat.span,
pat_info.top_info.hir_id, inner.span,
pat.span, "cannot implicitly match against multiple layers of reference",
inner.span, )
"cannot implicitly match against multiple layers of reference", }
)
} }
} }
@ -2317,10 +2388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("check_pat_ref: expected={:?}", expected); debug!("check_pat_ref: expected={:?}", expected);
match *expected.kind() { match *expected.kind() {
ty::Ref(_, r_ty, r_mutbl) 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 => || 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; pat_info.max_ref_mutbl = MutblCap::Not;
} }

View file

@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>(
let vis = cx.tcx.visibility(item.owner_id); let vis = cx.tcx.visibility(item.owner_id);
if vis.is_accessible_from(parent, cx.tcx) { if vis.is_accessible_from(parent, cx.tcx) {
accessible.push(item_name); accessible.push(item_name);
let path = if item_name == name { let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id));
// We know that the const wasn't in scope because it has the exact
// same name, so we suggest the full path.
with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
} else {
// The const is likely just typoed, and nothing else.
cx.tcx.def_path_str(item.owner_id)
};
accessible_path.push(path); accessible_path.push(path);
} else if name == item_name { } else if name == item_name {
// The const exists somewhere in this crate, but it can't be imported // The const exists somewhere in this crate, but it can't be imported

View file

@ -6,15 +6,14 @@ use std::mem;
use rustc_ast::attr::AttributeExt; use rustc_ast::attr::AttributeExt;
use rustc_ast::expand::StrippedCfgItem; use rustc_ast::expand::StrippedCfgItem;
use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr}; use rustc_ast::{self as ast, Crate, NodeId, attr};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_attr_parsing::StabilityLevel; use rustc_attr_parsing::StabilityLevel;
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, StashKey}; use rustc_errors::{Applicability, StashKey};
use rustc_expand::base::{ use rustc_expand::base::{
Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind,
SyntaxExtensionKind,
}; };
use rustc_expand::compile_declarative_macro; use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{ use rustc_expand::expand::{
@ -26,8 +25,8 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility}; use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{ use rustc_session::lint::builtin::{
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, SOFT_UNSTABLE, LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACRO_RULES, UNUSED_MACROS, UNUSED_MACRO_RULES, UNUSED_MACROS,
}; };
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::edit_distance::edit_distance; use rustc_span::edit_distance::edit_distance;
@ -157,26 +156,6 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
registered_tools registered_tools
} }
// Some feature gates for inner attributes are reported as lints for backward compatibility.
fn soft_custom_inner_attributes_gate(path: &ast::Path, invoc: &Invocation) -> bool {
match &path.segments[..] {
// `#![test]`
[seg] if seg.ident.name == sym::test => return true,
// `#![rustfmt::skip]` on out-of-line modules
[seg1, seg2] if seg1.ident.name == sym::rustfmt && seg2.ident.name == sym::skip => {
if let InvocationKind::Attr { item, .. } = &invoc.kind {
if let Annotatable::Item(item) = item {
if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, _, _)) = item.kind {
return true;
}
}
}
}
_ => {}
}
false
}
impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
fn next_node_id(&mut self) -> NodeId { fn next_node_id(&mut self) -> NodeId {
self.next_node_id() self.next_node_id()
@ -317,7 +296,6 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
parent_scope, parent_scope,
node_id, node_id,
force, force,
soft_custom_inner_attributes_gate(path, invoc),
deleg_impl, deleg_impl,
looks_like_invoc_in_mod_inert_attr, looks_like_invoc_in_mod_inert_attr,
)?; )?;
@ -549,7 +527,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent_scope: &ParentScope<'ra>, parent_scope: &ParentScope<'ra>,
node_id: NodeId, node_id: NodeId,
force: bool, force: bool,
soft_custom_inner_attributes_gate: bool,
deleg_impl: Option<LocalDefId>, deleg_impl: Option<LocalDefId>,
invoc_in_mod_inert_attr: Option<LocalDefId>, invoc_in_mod_inert_attr: Option<LocalDefId>,
) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> { ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
@ -667,22 +644,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Res::NonMacroAttr(..) => false, Res::NonMacroAttr(..) => false,
_ => unreachable!(), _ => unreachable!(),
}; };
if soft_custom_inner_attributes_gate { let msg = if is_macro {
self.tcx.sess.psess.buffer_lint( "inner macro attributes are unstable"
SOFT_UNSTABLE,
path.span,
node_id,
BuiltinLintDiag::InnerAttributeUnstable { is_macro },
);
} else { } else {
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::InnerAttributeUnstable`) "custom inner attributes are unstable"
let msg = if is_macro { };
"inner macro attributes are unstable" feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
} else {
"custom inner attributes are unstable"
};
feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
}
} }
if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)

View file

@ -19,11 +19,9 @@ use crate::sys_common::{AsInner, IntoInner};
use crate::{fs, io}; use crate::{fs, io};
/// Raw file descriptors. /// Raw file descriptors.
#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(target_os = "hermit"))] #[cfg(not(target_os = "hermit"))]
pub type RawFd = raw::c_int; pub type RawFd = raw::c_int;
#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_os = "hermit")] #[cfg(target_os = "hermit")]
pub type RawFd = i32; pub type RawFd = i32;
@ -33,7 +31,6 @@ pub type RawFd = i32;
/// This is only available on unix and WASI platforms and must be imported in /// This is only available on unix and WASI platforms and must be imported in
/// order to call the method. Windows platforms have a corresponding /// order to call the method. Windows platforms have a corresponding
/// `AsRawHandle` and `AsRawSocket` set of traits. /// `AsRawHandle` and `AsRawSocket` set of traits.
#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd { pub trait AsRawFd {
/// Extracts the raw file descriptor. /// Extracts the raw file descriptor.
@ -67,7 +64,6 @@ pub trait AsRawFd {
/// A trait to express the ability to construct an object from a raw file /// A trait to express the ability to construct an object from a raw file
/// descriptor. /// descriptor.
#[rustc_allowed_through_unstable_modules]
#[stable(feature = "from_raw_os", since = "1.1.0")] #[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd { pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file /// Constructs a new instance of `Self` from the given raw file
@ -112,7 +108,6 @@ pub trait FromRawFd {
/// A trait to express the ability to consume an object and acquire ownership of /// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor. /// its raw file descriptor.
#[rustc_allowed_through_unstable_modules]
#[stable(feature = "into_raw_os", since = "1.4.0")] #[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd { pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor. /// Consumes this object, returning the raw underlying file descriptor.

View file

@ -1,9 +0,0 @@
//! Owned and borrowed file descriptors.
#![unstable(feature = "wasi_ext", issue = "71213")]
// Tests for this module
#[cfg(test)]
mod tests;
pub use crate::os::fd::owned::*;

View file

@ -4,3 +4,7 @@
#[stable(feature = "io_safety_wasi", since = "1.65.0")] #[stable(feature = "io_safety_wasi", since = "1.65.0")]
pub use crate::os::fd::*; pub use crate::os::fd::*;
// Tests for this module
#[cfg(test)]
mod tests;

View file

@ -1,20 +0,0 @@
//! WASI-specific extensions to general I/O primitives.
#![unstable(feature = "wasi_ext", issue = "71213")]
// NOTE: despite the fact that this module is unstable,
// stable Rust had the capability to access the stable
// re-exported items from os::fd::raw through this
// unstable module.
// In PR #95956 the stability checker was changed to check
// all path segments of an item rather than just the last,
// which caused the aforementioned stable usage to regress
// (see issue #99502).
// As a result, the items in os::fd::raw were given the
// rustc_allowed_through_unstable_modules attribute.
// No regression tests were added to ensure this property,
// as CI is not configured to test wasm32-wasi.
// If this module is stabilized,
// you may want to remove those attributes
// (assuming no other unstable modules need them).
pub use crate::os::fd::raw::*;

View file

@ -32,9 +32,14 @@ use crate::{mem, panic, sys};
// - nothing (so this macro is a no-op) // - nothing (so this macro is a no-op)
macro_rules! rtprintpanic { macro_rules! rtprintpanic {
($($t:tt)*) => { ($($t:tt)*) => {
#[cfg(not(feature = "panic_immediate_abort"))]
if let Some(mut out) = crate::sys::stdio::panic_output() { if let Some(mut out) = crate::sys::stdio::panic_output() {
let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
} }
#[cfg(feature = "panic_immediate_abort")]
{
let _ = format_args!($($t)*);
}
} }
} }

View file

@ -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<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:24:17
|
LL | if let Some(&mut Some(x)) = &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:27:17
|
LL | if let Some(&mut Some(x)) = &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: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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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: Ref>() -> 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`.

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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: Ref>() -> 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`.

View file

@ -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: Ref>() -> 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]
}

View file

@ -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<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:24:17
|
LL | if let Some(&mut Some(x)) = &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:27:17
|
LL | if let Some(&mut Some(x)) = &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: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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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: Ref>() -> 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`.

View file

@ -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;
}

View file

@ -1,5 +1,5 @@
error[E0507]: cannot move out of a shared reference 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)) { 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 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; LL | let &ref mut x = &0;
| ^^^^^^^^^ cannot borrow as mutable | ^^^^^^^^^ cannot borrow as mutable

View file

@ -1,6 +1,9 @@
//@ edition: 2024 //@ edition: 2024
//@ revisions: classic structural
//! Tests for pattern errors not handled by the pattern typing rules, but by borrowck.
#![allow(incomplete_features)] #![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() { pub fn main() {
if let Some(&Some(x)) = Some(&Some(&mut 0)) { if let Some(&Some(x)) = Some(&Some(&mut 0)) {

View file

@ -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`.

View file

@ -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`.

View file

@ -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
}

View file

@ -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`.

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.

View file

@ -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;
}

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.

View file

@ -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`.

View file

@ -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
}
}

View file

@ -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<Option<&mut Option<{integer}>>>`
| |
| 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<Option<{integer}>>`
| |
| 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<Option<{integer}>>`
| |
| 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`.

View file

@ -1,7 +1,11 @@
//@ edition: 2024 //@ edition: 2024
//@ run-rustfix //@ 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)] #![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() { pub fn main() {
if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) {

View file

@ -1,5 +1,5 @@
error[E0596]: cannot borrow as mutable inside an `&` pattern 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)) { 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` | help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern 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)) { 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` | help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern 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; LL | let &pat!(x) = &mut 0;
| - ^ | - ^
@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0;
| help: replace this `&` with `&mut`: `&mut` | help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern 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); 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` | help: replace this `&` with `&mut`: `&mut`
error[E0596]: cannot borrow as mutable inside an `&` pattern 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); LL | let &(ref mut a, ref mut b) = &mut (true, false);
| - ^ | - ^

View file

@ -1,7 +1,11 @@
//@ edition: 2024 //@ edition: 2024
//@ run-rustfix //@ 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)] #![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() { pub fn main() {
if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {

View file

@ -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;
}

View file

@ -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`.

View file

@ -1,9 +1,9 @@
//@ run-pass //@ run-pass
//@ edition: 2021 //@ edition: 2021
//@ revisions: classic structural both //@ revisions: classic structural
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] #![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] #![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() { pub fn main() {
if let &Some(Some(x)) = &Some(&mut Some(0)) { if let &Some(Some(x)) = &Some(&mut Some(0)) {

View file

@ -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: Ref>() -> (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);
}

View file

@ -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: Ref>() -> (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`.

View file

@ -1,9 +1,11 @@
//@ run-pass
//@ edition: 2024 //@ 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)] #![allow(incomplete_features)]
#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] #![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))]
#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] #![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))]
pub fn main() { pub fn main() {
if let Some(Some(&x)) = &Some(&Some(0)) { if let Some(Some(&x)) = &Some(&Some(0)) {
@ -54,35 +56,4 @@ pub fn main() {
if let Some(&Some(x)) = &mut Some(Some(0)) { if let Some(&Some(x)) = &mut Some(Some(0)) {
let _: u32 = x; 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: Ref>() -> (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);
} }

View file

@ -1,7 +1,6 @@
//@ compile-flags: -Z span-debug //@ compile-flags: -Z span-debug
//@ error-pattern:custom inner attributes are unstable //@ error-pattern:custom inner attributes are unstable
//@ error-pattern:inner macro attributes are unstable //@ error-pattern:inner macro attributes are unstable
//@ error-pattern:this was previously accepted
//@ proc-macro: test-macros.rs //@ proc-macro: test-macros.rs
#![no_std] // Don't load unnecessary hygiene information from std #![no_std] // Don't load unnecessary hygiene information from std

View file

@ -1,3 +1,13 @@
error[E0658]: custom inner attributes are unstable
--> $DIR/module_with_attrs.rs:3:4
|
LL | #![rustfmt::skip]
| ^^^^^^^^^^^^^
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= help: add `#![feature(custom_inner_attributes)]` 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]: inner macro attributes are unstable error[E0658]: inner macro attributes are unstable
--> $DIR/module_with_attrs.rs:4:4 --> $DIR/module_with_attrs.rs:4:4
| |
@ -9,7 +19,7 @@ LL | #![print_attr]
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: non-inline modules in proc macro input are unstable error[E0658]: non-inline modules in proc macro input are unstable
--> $DIR/inner-attr-non-inline-mod.rs:14:1 --> $DIR/inner-attr-non-inline-mod.rs:13:1
| |
LL | mod module_with_attrs; LL | mod module_with_attrs;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
@ -19,7 +29,7 @@ LL | mod module_with_attrs;
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: custom inner attributes are unstable error[E0658]: custom inner attributes are unstable
--> $DIR/inner-attr-non-inline-mod.rs:14:1 --> $DIR/inner-attr-non-inline-mod.rs:13:1
| |
LL | mod module_with_attrs; LL | mod module_with_attrs;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
@ -28,27 +38,6 @@ LL | mod module_with_attrs;
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: custom inner attributes are unstable
--> $DIR/module_with_attrs.rs:3:4
|
LL | #![rustfmt::skip]
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
= note: `#[deny(soft_unstable)]` on by default
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`. For more information about this error, try `rustc --explain E0658`.
Future incompatibility report: Future breakage diagnostic:
error: custom inner attributes are unstable
--> $DIR/module_with_attrs.rs:3:4
|
LL | #![rustfmt::skip]
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
= note: `#[deny(soft_unstable)]` on by default

View file

@ -4,35 +4,35 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct { Punct {
ch: '#', ch: '#',
spacing: Alone, spacing: Alone,
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Group { Group {
delimiter: Bracket, delimiter: Bracket,
stream: TokenStream [ stream: TokenStream [
Ident { Ident {
ident: "deny", ident: "deny",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Group { Group {
delimiter: Parenthesis, delimiter: Parenthesis,
stream: TokenStream [ stream: TokenStream [
Ident { Ident {
ident: "unused_attributes", ident: "unused_attributes",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
], ],
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
], ],
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Ident { Ident {
ident: "mod", ident: "mod",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Ident { Ident {
ident: "module_with_attrs", ident: "module_with_attrs",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Group { Group {
delimiter: Brace, delimiter: Brace,
@ -40,38 +40,38 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
Punct { Punct {
ch: '#', ch: '#',
spacing: Joint, spacing: Joint,
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Punct { Punct {
ch: '!', ch: '!',
spacing: Alone, spacing: Alone,
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Group { Group {
delimiter: Bracket, delimiter: Bracket,
stream: TokenStream [ stream: TokenStream [
Ident { Ident {
ident: "rustfmt", ident: "rustfmt",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Punct { Punct {
ch: ':', ch: ':',
spacing: Joint, spacing: Joint,
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Punct { Punct {
ch: ':', ch: ':',
spacing: Alone, spacing: Alone,
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
Ident { Ident {
ident: "skip", ident: "skip",
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
], ],
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
], ],
span: $DIR/inner-attr-non-inline-mod.rs:14:1: 14:23 (#0), span: $DIR/inner-attr-non-inline-mod.rs:13:1: 13:23 (#0),
}, },
] ]

View file

@ -47,7 +47,6 @@ fn attrs() {
fn test_case() { fn test_case() {
#![test] //~ ERROR inner macro attributes are unstable #![test] //~ ERROR inner macro attributes are unstable
//~| WARN this was previously accepted
} }
fn main() {} fn main() {}

View file

@ -84,27 +84,16 @@ LL | let _x = #[identity_attr] println!();
= help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: inner macro attributes are unstable error[E0658]: inner macro attributes are unstable
--> $DIR/proc-macro-gates.rs:49:8 --> $DIR/proc-macro-gates.rs:49:8
| |
LL | #![test] LL | #![test]
| ^^^^ | ^^^^
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
= note: `#[deny(soft_unstable)]` on by default = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 10 previous errors error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0658`. For more information about this error, try `rustc --explain E0658`.
Future incompatibility report: Future breakage diagnostic:
error: inner macro attributes are unstable
--> $DIR/proc-macro-gates.rs:49:8
|
LL | #![test]
| ^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
= note: `#[deny(soft_unstable)]` on by default