Auto merge of #136980 - cuviper:beta-next, r=cuviper
[beta] backports - Pattern Migration 2024: try to suggest eliding redundant binding modifiers #136577, #136857 - chore: update rustc-hash 2.1.0 to 2.1.1 #136605 - Make `AsyncFnOnce`, `AsyncFnMut`, `AsyncFn` non-`#[fundamental]` #136724 - fix ensure_monomorphic_enough #136839 - Revert "Stabilize `extended_varargs_abi_support`" #136897, #136934 r? cuviper
This commit is contained in:
commit
461de7492e
32 changed files with 1077 additions and 255 deletions
16
Cargo.lock
16
Cargo.lock
|
|
@ -1983,7 +1983,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"clap",
|
||||
"fs-err",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustdoc-json-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -3152,7 +3152,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rinja_parser",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"syn 2.0.93",
|
||||
]
|
||||
|
|
@ -3216,9 +3216,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-main"
|
||||
|
|
@ -3620,7 +3620,7 @@ dependencies = [
|
|||
"memmap2",
|
||||
"parking_lot",
|
||||
"portable-atomic",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-rayon",
|
||||
"rustc-stable-hash",
|
||||
"rustc_arena",
|
||||
|
|
@ -4323,7 +4323,7 @@ dependencies = [
|
|||
name = "rustc_pattern_analysis"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc_abi",
|
||||
"rustc_apfloat",
|
||||
"rustc_arena",
|
||||
|
|
@ -4719,7 +4719,7 @@ name = "rustdoc-json-types"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
|
@ -5363,7 +5363,7 @@ dependencies = [
|
|||
"ignore",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"semver",
|
||||
"similar",
|
||||
"termcolor",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt};
|
||||
use tracing::debug;
|
||||
|
||||
use super::{InterpCx, MPlaceTy, MemoryKind, interp_ok, throw_inval};
|
||||
|
|
@ -20,44 +16,10 @@ where
|
|||
T: TypeVisitable<TyCtxt<'tcx>>,
|
||||
{
|
||||
debug!("ensure_monomorphic_enough: ty={:?}", ty);
|
||||
if !ty.has_param() {
|
||||
return interp_ok(());
|
||||
}
|
||||
|
||||
struct FoundParam;
|
||||
struct UsedParamsNeedInstantiationVisitor {}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor {
|
||||
type Result = ControlFlow<FoundParam>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
if !ty.has_param() {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
match *ty.kind() {
|
||||
ty::Param(_) => ControlFlow::Break(FoundParam),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::FnDef(..) => {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
_ => ty.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
|
||||
_ => c.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut vis = UsedParamsNeedInstantiationVisitor {};
|
||||
if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) {
|
||||
if ty.has_param() {
|
||||
throw_inval!(TooGeneric);
|
||||
} else {
|
||||
interp_ok(())
|
||||
}
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> {
|
||||
|
|
|
|||
|
|
@ -197,9 +197,6 @@ declare_features! (
|
|||
(accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)),
|
||||
/// Allows arbitrary expressions in key-value attributes at parse time.
|
||||
(accepted, extended_key_value_attributes, "1.54.0", Some(78835)),
|
||||
/// Allows using `efiapi`, `aapcs`, `sysv64` and `win64` as calling
|
||||
/// convention for functions with varargs.
|
||||
(accepted, extended_varargs_abi_support, "1.85.0", Some(100189)),
|
||||
/// Allows resolving absolute paths as paths from other crates.
|
||||
(accepted, extern_absolute_paths, "1.30.0", Some(44660)),
|
||||
/// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
|
||||
|
|
|
|||
|
|
@ -479,6 +479,9 @@ declare_features! (
|
|||
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
|
||||
/// Allows explicit tail calls via `become` expression.
|
||||
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
|
||||
/// Allows using `efiapi`, `sysv64` and `win64` as calling convention
|
||||
/// for functions with varargs.
|
||||
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
|
||||
/// Allows defining `extern type`s.
|
||||
(unstable, extern_types, "1.23.0", Some(43467)),
|
||||
/// Allow using 128-bit (quad precision) floating point numbers.
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ hir_analysis_value_of_associated_struct_already_specified =
|
|||
.label = re-bound here
|
||||
.previous_bound_label = `{$item_name}` bound here first
|
||||
|
||||
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
|
||||
.label = C-variadic function must have a compatible calling convention
|
||||
|
||||
hir_analysis_variances_of = {$variances}
|
||||
|
|
|
|||
|
|
@ -688,10 +688,11 @@ pub(crate) struct MainFunctionGenericParameters {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)]
|
||||
pub(crate) struct VariadicFunctionCompatibleConvention {
|
||||
pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub conventions: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ use rustc_middle::middle;
|
|||
use rustc_middle::mir::interpret::GlobalId;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
|
|
@ -113,9 +115,34 @@ fn require_c_abi_if_c_variadic(
|
|||
abi: ExternAbi,
|
||||
span: Span,
|
||||
) {
|
||||
if decl.c_variadic && !abi.supports_varargs() {
|
||||
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span });
|
||||
const CONVENTIONS_UNSTABLE: &str =
|
||||
"`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
|
||||
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
|
||||
const UNSTABLE_EXPLAIN: &str =
|
||||
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
|
||||
|
||||
if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
|
||||
return;
|
||||
}
|
||||
|
||||
let extended_abi_support = tcx.features().extended_varargs_abi_support();
|
||||
let conventions = match (extended_abi_support, abi.supports_varargs()) {
|
||||
// User enabled additional ABI support for varargs and function ABI matches those ones.
|
||||
(true, true) => return,
|
||||
|
||||
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
|
||||
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
|
||||
(false, true) => {
|
||||
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
|
||||
.emit();
|
||||
CONVENTIONS_STABLE
|
||||
}
|
||||
|
||||
(false, false) => CONVENTIONS_STABLE,
|
||||
(true, false) => CONVENTIONS_UNSTABLE,
|
||||
};
|
||||
|
||||
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
|
|
|||
|
|
@ -699,7 +699,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
// Determine the binding mode...
|
||||
let bm = match user_bind_annot {
|
||||
BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
|
||||
BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => {
|
||||
if pat.span.at_least_rust_2024()
|
||||
&& (self.tcx.features().ref_pat_eat_one_layer_2024()
|
||||
|| self.tcx.features().ref_pat_eat_one_layer_2024_structural())
|
||||
|
|
@ -719,22 +719,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// `mut` resets the binding mode on edition <= 2021
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat.span,
|
||||
pat,
|
||||
ident.span,
|
||||
"requires binding by-value, but the implicit default is by-reference",
|
||||
def_br_mutbl,
|
||||
);
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
}
|
||||
}
|
||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||
BindingMode(ByRef::Yes(_), _) => {
|
||||
if matches!(def_br, ByRef::Yes(_)) {
|
||||
if let ByRef::Yes(def_br_mutbl) = def_br {
|
||||
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat.span,
|
||||
pat,
|
||||
ident.span,
|
||||
"cannot override to bind by-reference when that is the implicit default",
|
||||
def_br_mutbl,
|
||||
);
|
||||
}
|
||||
user_bind_annot
|
||||
|
|
@ -2263,13 +2263,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
} else {
|
||||
// Reset binding mode on old editions
|
||||
if pat_info.binding_mode != ByRef::No {
|
||||
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat.span,
|
||||
pat,
|
||||
inner.span,
|
||||
"cannot implicitly match against multiple layers of reference",
|
||||
inh_mut,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2635,33 +2635,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
fn add_rust_2024_migration_desugared_pat(
|
||||
&self,
|
||||
pat_id: HirId,
|
||||
subpat_span: Span,
|
||||
subpat: &'tcx Pat<'tcx>,
|
||||
cutoff_span: Span,
|
||||
detailed_label: &str,
|
||||
def_br_mutbl: Mutability,
|
||||
) {
|
||||
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
|
||||
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
let cutoff_span = source_map
|
||||
.span_extend_prev_while(cutoff_span, char::is_whitespace)
|
||||
.span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
|
||||
.unwrap_or(cutoff_span);
|
||||
// Ensure we use the syntax context and thus edition of `subpat_span`; this will be a hard
|
||||
// Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
|
||||
// error if the subpattern is of edition >= 2024.
|
||||
let trimmed_span = subpat_span.until(cutoff_span).with_ctxt(subpat_span.ctxt());
|
||||
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
|
||||
|
||||
let mut typeck_results = self.typeck_results.borrow_mut();
|
||||
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
|
||||
// FIXME(ref_pat_eat_one_layer_2024): The migration diagnostic doesn't know how to track the
|
||||
// default binding mode in the presence of Rule 3 or Rule 5. As a consequence, the labels it
|
||||
// gives for default binding modes are wrong, as well as suggestions based on the default
|
||||
// binding mode. This keeps it from making those suggestions, as doing so could panic.
|
||||
let info = table.entry(pat_id).or_insert_with(|| ty::Rust2024IncompatiblePatInfo {
|
||||
primary_labels: Vec::new(),
|
||||
bad_modifiers: false,
|
||||
bad_ref_pats: false,
|
||||
suggest_eliding_modes: !self.tcx.features().ref_pat_eat_one_layer_2024()
|
||||
&& !self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
|
||||
});
|
||||
|
||||
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
|
||||
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
|
||||
let desc = if subpat_span.from_expansion() {
|
||||
"default binding mode is reset within expansion"
|
||||
let from_expansion = subpat.span.from_expansion();
|
||||
let primary_label = if from_expansion {
|
||||
// NB: This wording assumes the only expansions that can produce problematic reference
|
||||
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
|
||||
// so, we may want to inspect the span's source callee or macro backtrace.
|
||||
"occurs within macro expansion".to_owned()
|
||||
} else {
|
||||
detailed_label
|
||||
let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
|
||||
info.bad_modifiers |= true;
|
||||
// If the user-provided binding modifier doesn't match the default binding mode, we'll
|
||||
// need to suggest reference patterns, which can affect other bindings.
|
||||
// For simplicity, we opt to suggest making the pattern fully explicit.
|
||||
info.suggest_eliding_modes &=
|
||||
user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
|
||||
"binding modifier"
|
||||
} else {
|
||||
info.bad_ref_pats |= true;
|
||||
// For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
|
||||
// suggest adding them instead, which can affect the types assigned to bindings.
|
||||
// As such, we opt to suggest making the pattern fully explicit.
|
||||
info.suggest_eliding_modes = false;
|
||||
"reference pattern"
|
||||
};
|
||||
let dbm_str = match def_br_mutbl {
|
||||
Mutability::Not => "ref",
|
||||
Mutability::Mut => "ref mut",
|
||||
};
|
||||
format!("{pat_kind} not allowed under `{dbm_str}` default binding mode")
|
||||
};
|
||||
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.entry(pat_id)
|
||||
.or_default()
|
||||
.push((trimmed_span, desc.to_owned()));
|
||||
info.primary_labels.push((trimmed_span, primary_label));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ pub use self::sty::{
|
|||
pub use self::trait_def::TraitDef;
|
||||
pub use self::typeck_results::{
|
||||
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
|
||||
TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
|
||||
Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
|
||||
};
|
||||
pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ pub struct TypeckResults<'tcx> {
|
|||
/// Stores the actual binding mode for all instances of [`BindingMode`].
|
||||
pat_binding_modes: ItemLocalMap<BindingMode>,
|
||||
|
||||
/// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
|
||||
/// migration lint. Problematic subpatterns are stored in the `Vec` for the lint to highlight.
|
||||
rust_2024_migration_desugared_pats: ItemLocalMap<Vec<(Span, String)>>,
|
||||
/// Top-level patterns incompatible with Rust 2024's match ergonomics. These will be translated
|
||||
/// to a form valid in all Editions, either as a lint diagnostic or hard error.
|
||||
rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>,
|
||||
|
||||
/// Stores the types which were implicitly dereferenced in pattern binding modes
|
||||
/// for later usage in THIR lowering. For example,
|
||||
|
|
@ -420,7 +420,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
|
||||
pub fn rust_2024_migration_desugared_pats(
|
||||
&self,
|
||||
) -> LocalTableInContext<'_, Vec<(Span, String)>> {
|
||||
) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
|
||||
LocalTableInContext {
|
||||
hir_owner: self.hir_owner,
|
||||
data: &self.rust_2024_migration_desugared_pats,
|
||||
|
|
@ -429,7 +429,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
|
||||
pub fn rust_2024_migration_desugared_pats_mut(
|
||||
&mut self,
|
||||
) -> LocalTableInContextMut<'_, Vec<(Span, String)>> {
|
||||
) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
|
||||
LocalTableInContextMut {
|
||||
hir_owner: self.hir_owner,
|
||||
data: &mut self.rust_2024_migration_desugared_pats,
|
||||
|
|
@ -811,3 +811,17 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information on a pattern incompatible with Rust 2024, for use by the error/migration diagnostic
|
||||
/// emitted during THIR construction.
|
||||
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
|
||||
pub struct Rust2024IncompatiblePatInfo {
|
||||
/// Labeled spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
|
||||
pub primary_labels: Vec<(Span, String)>,
|
||||
/// Whether any binding modifiers occur under a non-`move` default binding mode.
|
||||
pub bad_modifiers: bool,
|
||||
/// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
|
||||
pub bad_ref_pats: bool,
|
||||
/// If `true`, we can give a simpler suggestion solely by eliding explicit binding modifiers.
|
||||
pub suggest_eliding_modes: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,7 +285,16 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
|
|||
|
||||
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
||||
|
||||
mir_build_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024
|
||||
mir_build_rust_2024_incompatible_pat = {$bad_modifiers ->
|
||||
*[true] binding modifiers{$bad_ref_pats ->
|
||||
*[true] {" "}and reference patterns
|
||||
[false] {""}
|
||||
}
|
||||
[false] reference patterns
|
||||
} may only be written when the default binding mode is `move`{$is_hard_error ->
|
||||
*[true] {""}
|
||||
[false] {" "}in Rust 2024
|
||||
}
|
||||
|
||||
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
||||
.attributes = no other attributes may be applied
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
||||
|
|
@ -1088,41 +1089,70 @@ pub(crate) enum RustcBoxAttrReason {
|
|||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_rust_2024_incompatible_pat)]
|
||||
pub(crate) struct Rust2024IncompatiblePat<'a> {
|
||||
pub(crate) struct Rust2024IncompatiblePat {
|
||||
#[subdiagnostic]
|
||||
pub(crate) sugg: Rust2024IncompatiblePatSugg<'a>,
|
||||
pub(crate) sugg: Rust2024IncompatiblePatSugg,
|
||||
pub(crate) bad_modifiers: bool,
|
||||
pub(crate) bad_ref_pats: bool,
|
||||
pub(crate) is_hard_error: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct Rust2024IncompatiblePatSugg<'a> {
|
||||
pub(crate) struct Rust2024IncompatiblePatSugg {
|
||||
/// If true, our suggestion is to elide explicit binding modifiers.
|
||||
/// If false, our suggestion is to make the pattern fully explicit.
|
||||
pub(crate) suggest_eliding_modes: bool,
|
||||
pub(crate) suggestion: Vec<(Span, String)>,
|
||||
pub(crate) ref_pattern_count: usize,
|
||||
pub(crate) binding_mode_count: usize,
|
||||
/// Labeled spans for subpatterns invalid in Rust 2024.
|
||||
pub(crate) labels: &'a [(Span, String)],
|
||||
/// Internal state: the ref-mutability of the default binding mode at the subpattern being
|
||||
/// lowered, with the span where it was introduced. `None` for a by-value default mode.
|
||||
pub(crate) default_mode_span: Option<(Span, ty::Mutability)>,
|
||||
/// Labels for where incompatibility-causing by-ref default binding modes were introduced.
|
||||
pub(crate) default_mode_labels: FxIndexMap<Span, ty::Mutability>,
|
||||
}
|
||||
|
||||
impl<'a> Subdiagnostic for Rust2024IncompatiblePatSugg<'a> {
|
||||
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
||||
self,
|
||||
diag: &mut Diag<'_, G>,
|
||||
_f: &F,
|
||||
) {
|
||||
// Format and emit explanatory notes about default binding modes. Reversing the spans' order
|
||||
// means if we have nested spans, the innermost ones will be visited first.
|
||||
for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
|
||||
// Don't point to a macro call site.
|
||||
if !span.from_expansion() {
|
||||
let note_msg = "matching on a reference type with a non-reference pattern changes the default binding mode";
|
||||
let label_msg =
|
||||
format!("this matches on type `{}_`", def_br_mutbl.ref_prefix_str());
|
||||
let mut label = MultiSpan::from(span);
|
||||
label.push_span_label(span, label_msg);
|
||||
diag.span_note(label, note_msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Format and emit the suggestion.
|
||||
let applicability =
|
||||
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
|
||||
Applicability::MachineApplicable
|
||||
} else {
|
||||
Applicability::MaybeIncorrect
|
||||
};
|
||||
let plural_derefs = pluralize!(self.ref_pattern_count);
|
||||
let and_modes = if self.binding_mode_count > 0 {
|
||||
format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
|
||||
let msg = if self.suggest_eliding_modes {
|
||||
let plural_modes = pluralize!(self.binding_mode_count);
|
||||
format!("remove the unnecessary binding modifier{plural_modes}")
|
||||
} else {
|
||||
String::new()
|
||||
let plural_derefs = pluralize!(self.ref_pattern_count);
|
||||
let and_modes = if self.binding_mode_count > 0 {
|
||||
format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
format!("make the implied reference pattern{plural_derefs}{and_modes} explicit")
|
||||
};
|
||||
diag.multipart_suggestion_verbose(
|
||||
format!("make the implied reference pattern{plural_derefs}{and_modes} explicit"),
|
||||
self.suggestion,
|
||||
applicability,
|
||||
);
|
||||
// FIXME(dianne): for peace of mind, don't risk emitting a 0-part suggestion (that panics!)
|
||||
if !self.suggestion.is_empty() {
|
||||
diag.multipart_suggestion_verbose(msg, self.suggestion, applicability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ struct PatCtxt<'a, 'tcx> {
|
|||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
|
||||
/// Used by the Rust 2024 migration lint.
|
||||
rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg<'a>>,
|
||||
rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg>,
|
||||
}
|
||||
|
||||
pub(super) fn pat_from_hir<'a, 'tcx>(
|
||||
|
|
@ -44,25 +44,30 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
) -> Box<Pat<'tcx>> {
|
||||
let migration_info = typeck_results.rust_2024_migration_desugared_pats().get(pat.hir_id);
|
||||
let mut pcx = PatCtxt {
|
||||
tcx,
|
||||
typing_env,
|
||||
typeck_results,
|
||||
rust_2024_migration_suggestion: typeck_results
|
||||
.rust_2024_migration_desugared_pats()
|
||||
.get(pat.hir_id)
|
||||
.map(|labels| Rust2024IncompatiblePatSugg {
|
||||
rust_2024_migration_suggestion: migration_info.and_then(|info| {
|
||||
Some(Rust2024IncompatiblePatSugg {
|
||||
suggest_eliding_modes: info.suggest_eliding_modes,
|
||||
suggestion: Vec::new(),
|
||||
ref_pattern_count: 0,
|
||||
binding_mode_count: 0,
|
||||
labels: labels.as_slice(),
|
||||
}),
|
||||
default_mode_span: None,
|
||||
default_mode_labels: Default::default(),
|
||||
})
|
||||
}),
|
||||
};
|
||||
let result = pcx.lower_pattern(pat);
|
||||
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
||||
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
|
||||
let mut spans = MultiSpan::from_spans(sugg.labels.iter().map(|(span, _)| *span).collect());
|
||||
for (span, label) in sugg.labels {
|
||||
if let Some(info) = migration_info
|
||||
&& let Some(sugg) = pcx.rust_2024_migration_suggestion
|
||||
{
|
||||
let mut spans =
|
||||
MultiSpan::from_spans(info.primary_labels.iter().map(|(span, _)| *span).collect());
|
||||
for (span, label) in &info.primary_labels {
|
||||
spans.push_span_label(*span, label.clone());
|
||||
}
|
||||
// If a relevant span is from at least edition 2024, this is a hard error.
|
||||
|
|
@ -70,10 +75,13 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||
if is_hard_error {
|
||||
let mut err =
|
||||
tcx.dcx().struct_span_err(spans, fluent::mir_build_rust_2024_incompatible_pat);
|
||||
if let Some(info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
|
||||
if let Some(lint_info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
|
||||
// provide the same reference link as the lint
|
||||
err.note(format!("for more information, see {}", info.reference));
|
||||
err.note(format!("for more information, see {}", lint_info.reference));
|
||||
}
|
||||
err.arg("bad_modifiers", info.bad_modifiers);
|
||||
err.arg("bad_ref_pats", info.bad_ref_pats);
|
||||
err.arg("is_hard_error", true);
|
||||
err.subdiagnostic(sugg);
|
||||
err.emit();
|
||||
} else {
|
||||
|
|
@ -81,7 +89,12 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
|
||||
pat.hir_id,
|
||||
spans,
|
||||
Rust2024IncompatiblePat { sugg },
|
||||
Rust2024IncompatiblePat {
|
||||
sugg,
|
||||
bad_modifiers: info.bad_modifiers,
|
||||
bad_ref_pats: info.bad_ref_pats,
|
||||
is_hard_error,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -90,6 +103,35 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||
|
||||
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||
let adjustments: &[Ty<'tcx>] =
|
||||
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
|
||||
|
||||
let mut opt_old_mode_span = None;
|
||||
if let Some(s) = &mut self.rust_2024_migration_suggestion
|
||||
&& !adjustments.is_empty()
|
||||
{
|
||||
let implicit_deref_mutbls = adjustments.iter().map(|ref_ty| {
|
||||
let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
|
||||
span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
|
||||
};
|
||||
mutbl
|
||||
});
|
||||
|
||||
if !s.suggest_eliding_modes {
|
||||
let suggestion_str: String =
|
||||
implicit_deref_mutbls.clone().map(|mutbl| mutbl.ref_prefix_str()).collect();
|
||||
s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
|
||||
s.ref_pattern_count += adjustments.len();
|
||||
}
|
||||
|
||||
// Remember if this changed the default binding mode, in case we want to label it.
|
||||
let min_mutbl = implicit_deref_mutbls.min().unwrap();
|
||||
if s.default_mode_span.is_none_or(|(_, old_mutbl)| min_mutbl < old_mutbl) {
|
||||
opt_old_mode_span = Some(s.default_mode_span);
|
||||
s.default_mode_span = Some((pat.span, min_mutbl));
|
||||
}
|
||||
};
|
||||
|
||||
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
|
||||
// pattern has the type that results *after* dereferencing. For example, in this code:
|
||||
//
|
||||
|
|
@ -118,8 +160,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
_ => self.lower_pattern_unadjusted(pat),
|
||||
};
|
||||
|
||||
let adjustments: &[Ty<'tcx>] =
|
||||
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
|
||||
let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| {
|
||||
debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty);
|
||||
Box::new(Pat {
|
||||
|
|
@ -130,24 +170,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
});
|
||||
|
||||
if let Some(s) = &mut self.rust_2024_migration_suggestion
|
||||
&& !adjustments.is_empty()
|
||||
&& let Some(old_mode_span) = opt_old_mode_span
|
||||
{
|
||||
let suggestion_str: String = adjustments
|
||||
.iter()
|
||||
.map(|ref_ty| {
|
||||
let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
|
||||
span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
|
||||
};
|
||||
|
||||
match mutbl {
|
||||
ty::Mutability::Not => "&",
|
||||
ty::Mutability::Mut => "&mut ",
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
|
||||
s.ref_pattern_count += adjustments.len();
|
||||
};
|
||||
s.default_mode_span = old_mode_span;
|
||||
}
|
||||
|
||||
adjusted_pat
|
||||
}
|
||||
|
|
@ -347,7 +373,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
|
||||
PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), mutability }
|
||||
}
|
||||
hir::PatKind::Ref(subpattern, _) | hir::PatKind::Box(subpattern) => {
|
||||
hir::PatKind::Ref(subpattern, _) => {
|
||||
// Track the default binding mode for the Rust 2024 migration suggestion.
|
||||
let old_mode_span = self.rust_2024_migration_suggestion.as_mut().and_then(|s| {
|
||||
if let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span {
|
||||
// If this eats a by-ref default binding mode, label the binding mode.
|
||||
s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
|
||||
}
|
||||
s.default_mode_span.take()
|
||||
});
|
||||
let subpattern = self.lower_pattern(subpattern);
|
||||
if let Some(s) = &mut self.rust_2024_migration_suggestion {
|
||||
s.default_mode_span = old_mode_span;
|
||||
}
|
||||
PatKind::Deref { subpattern }
|
||||
}
|
||||
hir::PatKind::Box(subpattern) => {
|
||||
PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
|
||||
}
|
||||
|
||||
|
|
@ -374,19 +415,32 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
.get(pat.hir_id)
|
||||
.expect("missing binding mode");
|
||||
|
||||
if let Some(s) = &mut self.rust_2024_migration_suggestion
|
||||
&& explicit_ba.0 == ByRef::No
|
||||
&& let ByRef::Yes(mutbl) = mode.0
|
||||
{
|
||||
let sugg_str = match mutbl {
|
||||
Mutability::Not => "ref ",
|
||||
Mutability::Mut => "ref mut ",
|
||||
};
|
||||
s.suggestion.push((
|
||||
pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
|
||||
sugg_str.to_owned(),
|
||||
));
|
||||
s.binding_mode_count += 1;
|
||||
if let Some(s) = &mut self.rust_2024_migration_suggestion {
|
||||
if explicit_ba != hir::BindingMode::NONE
|
||||
&& let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span
|
||||
{
|
||||
// If this overrides a by-ref default binding mode, label the binding mode.
|
||||
s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
|
||||
// If our suggestion is to elide redundnt modes, this will be one of them.
|
||||
if s.suggest_eliding_modes {
|
||||
s.suggestion.push((pat.span.with_hi(ident.span.lo()), String::new()));
|
||||
s.binding_mode_count += 1;
|
||||
}
|
||||
}
|
||||
if !s.suggest_eliding_modes
|
||||
&& explicit_ba.0 == ByRef::No
|
||||
&& let ByRef::Yes(mutbl) = mode.0
|
||||
{
|
||||
let sugg_str = match mutbl {
|
||||
Mutability::Not => "ref ",
|
||||
Mutability::Mut => "ref mut ",
|
||||
};
|
||||
s.suggestion.push((
|
||||
pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
|
||||
sugg_str.to_owned(),
|
||||
));
|
||||
s.binding_mode_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// A ref x pattern is the same node used for x, and as such it has
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use crate::marker::Tuple;
|
|||
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
|
||||
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
|
||||
#[rustc_paren_sugar]
|
||||
#[fundamental]
|
||||
#[must_use = "async closures are lazy and do nothing unless called"]
|
||||
#[lang = "async_fn"]
|
||||
pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
|
||||
|
|
@ -22,7 +21,6 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
|
|||
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
|
||||
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
|
||||
#[rustc_paren_sugar]
|
||||
#[fundamental]
|
||||
#[must_use = "async closures are lazy and do nothing unless called"]
|
||||
#[lang = "async_fn_mut"]
|
||||
pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
|
||||
|
|
@ -44,7 +42,6 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
|
|||
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
|
||||
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
|
||||
#[rustc_paren_sugar]
|
||||
#[fundamental]
|
||||
#[must_use = "async closures are lazy and do nothing unless called"]
|
||||
#[lang = "async_fn_once"]
|
||||
pub trait AsyncFnOnce<Args: Tuple> {
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@
|
|||
#![feature(doc_masked)]
|
||||
#![feature(doc_notable_trait)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(extended_varargs_abi_support)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(formatting_options)]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# `extended_varargs_abi_support`
|
||||
|
||||
The tracking issue for this feature is: [#100189]
|
||||
|
||||
[#100189]: https://github.com/rust-lang/rust/issues/100189
|
||||
|
||||
------------------------
|
||||
|
||||
This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
|
||||
conventions on functions with varargs.
|
||||
12
tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
Normal file
12
tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
- // MIR for `cursed_is_i32` before GVN
|
||||
+ // MIR for `cursed_is_i32` after GVN
|
||||
|
||||
fn cursed_is_i32() -> bool {
|
||||
let mut _0: bool;
|
||||
|
||||
bb0: {
|
||||
_0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
22
tests/mir-opt/gvn_type_id_polymorphic.rs
Normal file
22
tests/mir-opt/gvn_type_id_polymorphic.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//@ test-mir-pass: GVN
|
||||
//@ compile-flags: -C opt-level=2
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
fn generic<T>() {}
|
||||
|
||||
const fn type_id_of_val<T: 'static>(_: &T) -> u128 {
|
||||
std::intrinsics::type_id::<T>()
|
||||
}
|
||||
|
||||
// EMIT_MIR gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
|
||||
fn cursed_is_i32<T: 'static>() -> bool {
|
||||
// CHECK-LABEL: fn cursed_is_i32(
|
||||
// CHECK: _0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
|
||||
// CHECK-NEXT: return;
|
||||
(const { type_id_of_val(&generic::<T>) } == const { type_id_of_val(&generic::<i32>) })
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dbg!(cursed_is_i32::<i32>());
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
//@ only-x86_64
|
||||
|
||||
fn efiapi(f: extern "efiapi" fn(usize, ...)) {
|
||||
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
f(22, 44);
|
||||
}
|
||||
fn sysv(f: extern "sysv64" fn(usize, ...)) {
|
||||
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
f(22, 44);
|
||||
}
|
||||
fn win(f: extern "win64" fn(usize, ...)) {
|
||||
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
f(22, 44);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
|
||||
|
|
||||
LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
|
||||
= help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
|
||||
|
|
||||
LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
|
||||
|
||||
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
|
||||
|
|
||||
LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
|
||||
= help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
|
||||
|
|
||||
LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
|
||||
|
||||
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
|
||||
|
|
||||
LL | fn win(f: extern "win64" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
|
||||
= help: add `#![feature(extended_varargs_abi_support)]` 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[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
|
||||
|
|
||||
LL | fn win(f: extern "win64" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0045, E0658.
|
||||
For more information about an error, try `rustc --explain E0045`.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/variadic-ffi-1.rs:9:5
|
||||
|
|
||||
LL | fn printf(_: *const u8, ...);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ only-arm
|
||||
//@ build-pass
|
||||
#![feature(extended_varargs_abi_support)]
|
||||
|
||||
fn aapcs(f: extern "aapcs" fn(usize, ...)) {
|
||||
f(22, 44);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ ignore-arm stdcall isn't supported
|
||||
#![feature(extended_varargs_abi_support)]
|
||||
|
||||
#[allow(unsupported_fn_ptr_calling_conventions)]
|
||||
fn baz(f: extern "stdcall" fn(usize, ...)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||
--> $DIR/variadic-ffi-2.rs:4:11
|
||||
--> $DIR/variadic-ffi-2.rs:5:11
|
||||
|
|
||||
LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
|
||||
|
|
|
|||
|
|
@ -39,4 +39,4 @@ type WithTransparentTraitObject =
|
|||
//~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798]
|
||||
|
||||
type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);
|
||||
//~^ ERROR C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` [E0045]
|
||||
//~^ ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl` [E0045]
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ LL | extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspa
|
|||
= note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
|
||||
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||
|
||||
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/generics.rs:41:20
|
||||
|
|
||||
LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
|
||||
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
|
||||
--> $DIR/E0045.rs:1:17
|
||||
|
|
||||
LL | extern "Rust" { fn foo(x: u8, ...); }
|
||||
|
|
|
|||
|
|
@ -23,22 +23,22 @@ fn main() {
|
|||
assert_type_eq(x, &mut 0u8);
|
||||
|
||||
let &Foo(mut x) = &Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(mut x) = &mut Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(ref x) = &Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
let Foo(x) = &Foo(0);
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &mut Foo(ref x) = &mut Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
|
|
@ -55,22 +55,22 @@ fn main() {
|
|||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &Foo(&x) = &Foo(&0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(&mut x) = &Foo(&mut 0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(&x) = &mut Foo(&0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(&mut x) = &mut Foo(&mut 0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
|
|
@ -79,25 +79,25 @@ fn main() {
|
|||
}
|
||||
|
||||
if let &&&&&Some(&x) = &&&&&Some(&0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
}
|
||||
|
|
@ -109,20 +109,20 @@ fn main() {
|
|||
}
|
||||
|
||||
let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &&0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
|
||||
if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||
{
|
||||
|
|
@ -135,10 +135,108 @@ fn main() {
|
|||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
&(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
||||
assert_type_eq(x, 0u32);
|
||||
assert_type_eq(y, 0u32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let &mut [&mut &[ref a]] = &mut [&mut &[0]];
|
||||
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
let &[&(_)] = &[&0];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
|
||||
// NB: Most of the following tests are for possible future improvements to migration suggestions
|
||||
|
||||
// Test removing multiple binding modifiers.
|
||||
let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when removing binding modifiers.
|
||||
let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &mut 0u32);
|
||||
assert_type_eq(c, &mut 0u32);
|
||||
|
||||
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
|
||||
let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that we don't change bindings' types when removing reference patterns.
|
||||
let &Foo(&ref a) = &Foo(&0);
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when adding reference paterns (caught early).
|
||||
let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
assert_type_eq(d, &0u32);
|
||||
assert_type_eq(e, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when adding reference patterns (caught late).
|
||||
let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, 0u32);
|
||||
|
||||
// Test featuring both additions and removals.
|
||||
let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that bindings' subpatterns' modes are updated properly.
|
||||
let &[mut a @ ref b] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
|
||||
// Test that bindings' subpatterns' modes are checked properly.
|
||||
let &[ref a @ mut b] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
|
||||
let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
assert_type_eq(d, 0u32);
|
||||
|
||||
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
|
||||
let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &[0u32]);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &[0u32]);
|
||||
assert_type_eq(d, 0u32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,22 +23,22 @@ fn main() {
|
|||
assert_type_eq(x, &mut 0u8);
|
||||
|
||||
let Foo(mut x) = &Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(mut x) = &mut Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(ref x) = &Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(ref x) = &mut Foo(0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
|
|
@ -55,22 +55,22 @@ fn main() {
|
|||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(&x) = &Foo(&0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&mut x) = &Foo(&mut 0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&x) = &mut Foo(&0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&mut x) = &mut Foo(&mut 0);
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
|
|
@ -79,25 +79,25 @@ fn main() {
|
|||
}
|
||||
|
||||
if let Some(&x) = &&&&&Some(&0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
}
|
||||
|
|
@ -109,20 +109,20 @@ fn main() {
|
|||
}
|
||||
|
||||
let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &&0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
|
||||
if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||
{
|
||||
|
|
@ -135,10 +135,108 @@ fn main() {
|
|||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
//~^ ERROR: this pattern relies on behavior which may change in edition 2024
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
||||
assert_type_eq(x, 0u32);
|
||||
assert_type_eq(y, 0u32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let [&mut [ref a]] = &mut [&mut &[0]];
|
||||
//~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
let [&(_)] = &[&0];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
|
||||
// NB: Most of the following tests are for possible future improvements to migration suggestions
|
||||
|
||||
// Test removing multiple binding modifiers.
|
||||
let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when removing binding modifiers.
|
||||
let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &mut 0u32);
|
||||
assert_type_eq(c, &mut 0u32);
|
||||
|
||||
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
|
||||
let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that we don't change bindings' types when removing reference patterns.
|
||||
let Foo(&ref a) = &Foo(&0);
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when adding reference paterns (caught early).
|
||||
let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
assert_type_eq(d, &0u32);
|
||||
assert_type_eq(e, &0u32);
|
||||
|
||||
// Test that we don't change bindings' modes when adding reference patterns (caught late).
|
||||
let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, 0u32);
|
||||
|
||||
// Test featuring both additions and removals.
|
||||
let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
|
||||
// Test that bindings' subpatterns' modes are updated properly.
|
||||
let [mut a @ b] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
|
||||
// Test that bindings' subpatterns' modes are checked properly.
|
||||
let [a @ mut b] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
|
||||
let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &0u32);
|
||||
assert_type_eq(d, 0u32);
|
||||
|
||||
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
|
||||
let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &[0u32]);
|
||||
assert_type_eq(b, &0u32);
|
||||
assert_type_eq(c, &[0u32]);
|
||||
assert_type_eq(d, 0u32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:25:13
|
||||
|
|
||||
LL | let Foo(mut x) = &Foo(0);
|
||||
| ^^^ requires binding by-value, but the implicit default is by-reference
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:25:9
|
||||
|
|
||||
LL | let Foo(mut x) = &Foo(0);
|
||||
| ^^^^^^^^^^ this matches on type `&_`
|
||||
note: the lint level is defined here
|
||||
--> $DIR/migration_lint.rs:7:9
|
||||
|
|
||||
|
|
@ -16,206 +21,546 @@ help: make the implied reference pattern explicit
|
|||
LL | let &Foo(mut x) = &Foo(0);
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:30:13
|
||||
|
|
||||
LL | let Foo(mut x) = &mut Foo(0);
|
||||
| ^^^ requires binding by-value, but the implicit default is by-reference
|
||||
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:30:9
|
||||
|
|
||||
LL | let Foo(mut x) = &mut Foo(0);
|
||||
| ^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &mut Foo(mut x) = &mut Foo(0);
|
||||
| ++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:35:13
|
||||
|
|
||||
LL | let Foo(ref x) = &Foo(0);
|
||||
| ^^^ cannot override to bind by-reference when that is the implicit default
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
help: make the implied reference pattern explicit
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:35:9
|
||||
|
|
||||
LL | let Foo(ref x) = &Foo(0);
|
||||
| ^^^^^^^^^^ this matches on type `&_`
|
||||
help: remove the unnecessary binding modifier
|
||||
|
|
||||
LL - let Foo(ref x) = &Foo(0);
|
||||
LL + let Foo(x) = &Foo(0);
|
||||
|
|
||||
LL | let &Foo(ref x) = &Foo(0);
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:40:13
|
||||
|
|
||||
LL | let Foo(ref x) = &mut Foo(0);
|
||||
| ^^^ cannot override to bind by-reference when that is the implicit default
|
||||
| ^^^ binding modifier not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:40:9
|
||||
|
|
||||
LL | let Foo(ref x) = &mut Foo(0);
|
||||
| ^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &mut Foo(ref x) = &mut Foo(0);
|
||||
| ++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:57:13
|
||||
|
|
||||
LL | let Foo(&x) = &Foo(&0);
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:57:9
|
||||
|
|
||||
LL | let Foo(&x) = &Foo(&0);
|
||||
| ^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &Foo(&x) = &Foo(&0);
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:62:13
|
||||
|
|
||||
LL | let Foo(&mut x) = &Foo(&mut 0);
|
||||
| ^^^^ cannot implicitly match against multiple layers of reference
|
||||
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:62:9
|
||||
|
|
||||
LL | let Foo(&mut x) = &Foo(&mut 0);
|
||||
| ^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &Foo(&mut x) = &Foo(&mut 0);
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:67:13
|
||||
|
|
||||
LL | let Foo(&x) = &mut Foo(&0);
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:67:9
|
||||
|
|
||||
LL | let Foo(&x) = &mut Foo(&0);
|
||||
| ^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &mut Foo(&x) = &mut Foo(&0);
|
||||
| ++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:72:13
|
||||
|
|
||||
LL | let Foo(&mut x) = &mut Foo(&mut 0);
|
||||
| ^^^^ cannot implicitly match against multiple layers of reference
|
||||
| ^^^^ reference pattern not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:72:9
|
||||
|
|
||||
LL | let Foo(&mut x) = &mut Foo(&mut 0);
|
||||
| ^^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &mut Foo(&mut x) = &mut Foo(&mut 0);
|
||||
| ++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:81:17
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&Some(&0u8) {
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:81:12
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&Some(&0u8) {
|
||||
| ^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) {
|
||||
| +++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:87:17
|
||||
|
|
||||
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
| ^^^^ cannot implicitly match against multiple layers of reference
|
||||
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:87:12
|
||||
|
|
||||
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
| ^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
| +++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:93:17
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:93:12
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||
| ^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
|
||||
| ++++++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:99:17
|
||||
|
|
||||
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
| ^^^^ cannot implicitly match against multiple layers of reference
|
||||
| ^^^^ reference pattern not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:99:12
|
||||
|
|
||||
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference patterns and variable binding mode explicit
|
||||
|
|
||||
LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
| ++++ ++++ +++++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:111:21
|
||||
|
|
||||
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^ requires binding by-value, but the implicit default is by-reference
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:111:9
|
||||
|
|
||||
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern and variable binding modes explicit
|
||||
|
|
||||
LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| + +++ +++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:117:21
|
||||
|
|
||||
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
| ^ ^^^ cannot override to bind by-reference when that is the implicit default
|
||||
| ^ ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
| |
|
||||
| cannot implicitly match against multiple layers of reference
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:117:9
|
||||
|
|
||||
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern and variable binding mode explicit
|
||||
|
|
||||
LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
| + +++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:124:24
|
||||
|
|
||||
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||
| ^ ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ ^ reference pattern not allowed under `ref` default binding mode
|
||||
| |
|
||||
| cannot implicitly match against multiple layers of reference
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:124:12
|
||||
|
|
||||
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns and variable binding mode explicit
|
||||
|
|
||||
LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||
| + + + +++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move`
|
||||
--> $DIR/migration_lint.rs:137:15
|
||||
|
|
||||
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ default binding mode is reset within expansion
|
||||
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
|
||||
| |
|
||||
| requires binding by-value, but the implicit default is by-reference
|
||||
| binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:137:9
|
||||
|
|
||||
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
= note: this error originates in the macro `migration_lint_macros::mixed_edition_pat` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
| +
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:145:10
|
||||
|
|
||||
LL | let [&mut [ref a]] = &mut [&mut &[0]];
|
||||
| ^^^^ ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
| |
|
||||
| reference pattern not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:145:15
|
||||
|
|
||||
LL | let [&mut [ref a]] = &mut [&mut &[0]];
|
||||
| ^^^^^^^ this matches on type `&_`
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:145:9
|
||||
|
|
||||
LL | let [&mut [ref a]] = &mut [&mut &[0]];
|
||||
| ^^^^^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]];
|
||||
| ++++ +
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:150:10
|
||||
|
|
||||
LL | let [&(_)] = &[&0];
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:150:9
|
||||
|
|
||||
LL | let [&(_)] = &[&0];
|
||||
| ^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &[&(_)] = &[&0];
|
||||
| +
|
||||
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:157:18
|
||||
|
|
||||
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^ ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
| |
|
||||
| binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:157:9
|
||||
|
|
||||
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: remove the unnecessary binding modifiers
|
||||
|
|
||||
LL - let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
LL + let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
|
|
||||
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:164:18
|
||||
|
|
||||
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^ ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
||||
| |
|
||||
| binding modifier not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:164:9
|
||||
|
|
||||
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: make the implied reference pattern and variable binding mode explicit
|
||||
|
|
||||
LL | let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
|
||||
| ++++ +++++++
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:172:21
|
||||
|
|
||||
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
|
||||
| ^ ^^^^ reference pattern not allowed under `ref` default binding mode
|
||||
| |
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:172:9
|
||||
|
|
||||
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns and variable binding modes explicit
|
||||
|
|
||||
LL | let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
|
||||
| ++++++ + +++ +++
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:180:13
|
||||
|
|
||||
LL | let Foo(&ref a) = &Foo(&0);
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:180:9
|
||||
|
|
||||
LL | let Foo(&ref a) = &Foo(&0);
|
||||
| ^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &Foo(&ref a) = &Foo(&0);
|
||||
| +
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:186:10
|
||||
|
|
||||
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:186:9
|
||||
|
|
||||
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns and variable binding modes explicit
|
||||
|
|
||||
LL | let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
|
||||
| + +++ + +++ ++++ ++++ +++ + +++
|
||||
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:196:19
|
||||
|
|
||||
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:196:9
|
||||
|
|
||||
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
|
||||
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns and variable binding modes explicit
|
||||
|
|
||||
LL | let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
|
||||
| + +++ ++++ +++ +
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:204:10
|
||||
|
|
||||
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
|
||||
| ^ ^ reference pattern not allowed under `ref` default binding mode
|
||||
| |
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:204:9
|
||||
|
|
||||
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
|
||||
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns and variable binding mode explicit
|
||||
|
|
||||
LL | let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
|
||||
| + ++++ +++
|
||||
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:212:10
|
||||
|
|
||||
LL | let [mut a @ b] = &[0];
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:212:9
|
||||
|
|
||||
LL | let [mut a @ b] = &[0];
|
||||
| ^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern and variable binding mode explicit
|
||||
|
|
||||
LL | let &[mut a @ ref b] = &[0];
|
||||
| + +++
|
||||
|
||||
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:219:14
|
||||
|
|
||||
LL | let [a @ mut b] = &[0];
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:219:9
|
||||
|
|
||||
LL | let [a @ mut b] = &[0];
|
||||
| ^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern and variable binding mode explicit
|
||||
|
|
||||
LL | let &[ref a @ mut b] = &[0];
|
||||
| + +++
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:226:14
|
||||
|
|
||||
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
| ^ ^ reference pattern not allowed under `ref` default binding mode
|
||||
| |
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:226:31
|
||||
|
|
||||
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
| ^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:226:10
|
||||
|
|
||||
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
|
||||
| + +
|
||||
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:235:14
|
||||
|
|
||||
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
| ^ ^ reference pattern not allowed under `ref` default binding mode
|
||||
| |
|
||||
| reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:235:33
|
||||
|
|
||||
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:235:10
|
||||
|
|
||||
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference patterns explicit
|
||||
|
|
||||
LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
|
||||
| + +
|
||||
|
||||
error: aborting due to 29 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ macro_rules! test_pat_on_type {
|
|||
}
|
||||
|
||||
test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
|
||||
test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
|
||||
test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
|
||||
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
|
||||
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
|
||||
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
|
||||
|
||||
fn get<X>() -> X {
|
||||
unimplemented!()
|
||||
|
|
@ -40,6 +40,6 @@ fn get<X>() -> X {
|
|||
// Make sure this works even when the underlying type is inferred. This test passes on rust stable.
|
||||
fn infer<X: Copy>() -> X {
|
||||
match &get() {
|
||||
(&x,) => x, //~ ERROR this pattern relies on behavior which may change in edition 2024
|
||||
(&x,) => x, //~ ERROR reference patterns may only be written when the default binding mode is `move`
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,85 +99,122 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
|
|||
LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
|
||||
|
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:24:20
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &(&T,)];
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:24:19
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &(&T,)];
|
||||
| ^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | test_pat_on_type![&(&x,): &(&T,)];
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
||||
|
|
||||
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
|
||||
| ^^^^ cannot implicitly match against multiple layers of reference
|
||||
| ^^^^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:27:19
|
||||
|
|
||||
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
|
||||
| ^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | test_pat_on_type![&(&mut x,): &(&mut T,)];
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:31:28
|
||||
|
|
||||
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:31:19
|
||||
|
|
||||
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
|
||||
| ^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo];
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:32:20
|
||||
|
|
||||
LL | test_pat_on_type![(mut x,): &(T,)];
|
||||
| ^^^ requires binding by-value, but the implicit default is by-reference
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:32:19
|
||||
|
|
||||
LL | test_pat_on_type![(mut x,): &(T,)];
|
||||
| ^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | test_pat_on_type![&(mut x,): &(T,)];
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:33:20
|
||||
|
|
||||
LL | test_pat_on_type![(ref x,): &(T,)];
|
||||
| ^^^ cannot override to bind by-reference when that is the implicit default
|
||||
| ^^^ binding modifier not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
help: make the implied reference pattern explicit
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:33:19
|
||||
|
|
||||
LL | test_pat_on_type![(ref x,): &(T,)];
|
||||
| ^^^^^^^^ this matches on type `&_`
|
||||
help: remove the unnecessary binding modifier
|
||||
|
|
||||
LL - test_pat_on_type![(ref x,): &(T,)];
|
||||
LL + test_pat_on_type![(x,): &(T,)];
|
||||
|
|
||||
LL | test_pat_on_type![&(ref x,): &(T,)];
|
||||
| +
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: binding modifiers may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:34:20
|
||||
|
|
||||
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
|
||||
| ^^^^^^^ cannot override to bind by-reference when that is the implicit default
|
||||
| ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
help: make the implied reference pattern explicit
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:34:19
|
||||
|
|
||||
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
|
||||
| ^^^^^^^^^^^^ this matches on type `&mut _`
|
||||
help: remove the unnecessary binding modifier
|
||||
|
|
||||
LL - test_pat_on_type![(ref mut x,): &mut (T,)];
|
||||
LL + test_pat_on_type![(x,): &mut (T,)];
|
||||
|
|
||||
LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)];
|
||||
| ++++
|
||||
|
||||
error: this pattern relies on behavior which may change in edition 2024
|
||||
error: reference patterns may only be written when the default binding mode is `move`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:43:10
|
||||
|
|
||||
LL | (&x,) => x,
|
||||
| ^ cannot implicitly match against multiple layers of reference
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/min_match_ergonomics_fail.rs:43:9
|
||||
|
|
||||
LL | (&x,) => x,
|
||||
| ^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | &(&x,) => x,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue