1
Fork 0

Auto merge of #126056 - matthiaskrgr:rollup-ytwg62v, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #124731 (Add translation support by mdbook-i18n-helpers to bootstrap)
 - #125168 (Match ergonomics 2024: align implementation with RFC)
 - #125925 (Don't trigger `unsafe_op_in_unsafe_fn` for deprecated safe fns)
 - #125987 (When `derive`ing, account for HRTB on `BareFn` fields)
 - #126045 (check_expr_struct_fields: taint context with errors if struct definit…)
 - #126048 (Fix typos in cargo-specifics.md)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-06-06 05:56:06 +00:00
commit 2b6a34273d
35 changed files with 642 additions and 425 deletions

View file

@ -372,7 +372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [ dependencies = [
"memchr", "memchr",
"regex-automata 0.3.9", "regex-automata 0.3.7",
"serde", "serde",
] ]
@ -2206,6 +2206,21 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "line-wrap"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e"
[[package]]
name = "linereader"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d921fea6860357575519aca014c6e22470585accdd543b370c404a8a72d0dd1d"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "linkchecker" name = "linkchecker"
version = "0.1.0" version = "0.1.0"
@ -2214,6 +2229,12 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]] [[package]]
name = "lint-docs" name = "lint-docs"
version = "0.1.0" version = "0.1.0"
@ -2364,6 +2385,25 @@ dependencies = [
"topological-sort", "topological-sort",
] ]
[[package]]
name = "mdbook-i18n-helpers"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f71f5961d6f3376e1ff3e5989c2e3ecccc3e8a00f3a3acde446847f84852e4"
dependencies = [
"anyhow",
"chrono",
"mdbook",
"polib",
"pulldown-cmark 0.10.3",
"pulldown-cmark-to-cmark",
"regex",
"semver",
"serde_json",
"syntect",
"textwrap",
]
[[package]] [[package]]
name = "mdbook-trpl-listing" name = "mdbook-trpl-listing"
version = "0.1.0" version = "0.1.0"
@ -2650,6 +2690,28 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags 1.3.2",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]] [[package]]
name = "opener" name = "opener"
version = "0.6.1" version = "0.6.1"
@ -2968,6 +3030,29 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "plist"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9"
dependencies = [
"base64",
"indexmap",
"line-wrap",
"quick-xml",
"serde",
"time",
]
[[package]]
name = "polib"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b393b155cf9be86249cba1b56cc81be0e6212c66d94ac0d76d37a1761f3bb1b"
dependencies = [
"linereader",
]
[[package]] [[package]]
name = "polonius-engine" name = "polonius-engine"
version = "0.13.0" version = "0.13.0"
@ -3126,6 +3211,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe" checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe"
[[package]]
name = "quick-xml"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quine-mc_cluskey" name = "quine-mc_cluskey"
version = "0.2.4" version = "0.2.4"
@ -3261,12 +3355,13 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.8.4" version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-automata 0.3.7",
"regex-syntax 0.7.5", "regex-syntax 0.7.5",
] ]
@ -3290,9 +3385,14 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.3.9" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.7.5",
]
[[package]] [[package]]
name = "regex-lite" name = "regex-lite"
@ -3367,6 +3467,7 @@ dependencies = [
"clap", "clap",
"env_logger", "env_logger",
"mdbook", "mdbook",
"mdbook-i18n-helpers",
"mdbook-trpl-listing", "mdbook-trpl-listing",
"mdbook-trpl-note", "mdbook-trpl-note",
] ]
@ -5372,6 +5473,28 @@ dependencies = [
"syn 2.0.64", "syn 2.0.64",
] ]
[[package]]
name = "syntect"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
dependencies = [
"bincode",
"bitflags 1.3.2",
"flate2",
"fnv",
"once_cell",
"onig",
"plist",
"regex-syntax 0.8.3",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"walkdir",
"yaml-rust",
]
[[package]] [[package]]
name = "sysinfo" name = "sysinfo"
version = "0.30.12" version = "0.30.12"
@ -5497,6 +5620,12 @@ dependencies = [
"std", "std",
] ]
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]] [[package]]
name = "thin-vec" name = "thin-vec"
version = "0.2.13" version = "0.2.13"
@ -6476,6 +6605,15 @@ dependencies = [
"lzma-sys", "lzma-sys",
] ]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]] [[package]]
name = "yansi-term" name = "yansi-term"
version = "0.1.2" version = "0.1.2"

View file

@ -412,6 +412,15 @@ fn find_type_parameters(
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> { impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
fn visit_ty(&mut self, ty: &'a ast::Ty) { fn visit_ty(&mut self, ty: &'a ast::Ty) {
let stack_len = self.bound_generic_params_stack.len();
if let ast::TyKind::BareFn(bare_fn) = &ty.kind
&& !bare_fn.generic_params.is_empty()
{
// Given a field `x: for<'a> fn(T::SomeType<'a>)`, we wan't to account for `'a` so
// that we generate `where for<'a> T::SomeType<'a>: ::core::clone::Clone`. #122622
self.bound_generic_params_stack.extend(bare_fn.generic_params.iter().cloned());
}
if let ast::TyKind::Path(_, path) = &ty.kind if let ast::TyKind::Path(_, path) = &ty.kind
&& let Some(segment) = path.segments.first() && let Some(segment) = path.segments.first()
&& self.ty_param_names.contains(&segment.ident.name) && self.ty_param_names.contains(&segment.ident.name)
@ -422,7 +431,8 @@ fn find_type_parameters(
}); });
} }
visit::walk_ty(self, ty) visit::walk_ty(self, ty);
self.bound_generic_params_stack.truncate(stack_len);
} }
// Place bound generic params on a stack, to extract them when a type is encountered. // Place bound generic params on a stack, to extract them when a type is encountered.

View file

@ -128,6 +128,8 @@ declare_features! (
/// Allows the use of type alias impl trait in function return positions /// Allows the use of type alias impl trait in function return positions
(removed, min_type_alias_impl_trait, "1.56.0", Some(63063), (removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
Some("removed in favor of full type_alias_impl_trait")), Some("removed in favor of full type_alias_impl_trait")),
/// Make `mut` not reset the binding mode on edition >= 2024.
(removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")),
(removed, needs_allocator, "1.4.0", Some(27389), (removed, needs_allocator, "1.4.0", Some(27389),
Some("subsumed by `#![feature(allocator_internals)]`")), Some("subsumed by `#![feature(allocator_internals)]`")),
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
@ -181,6 +183,7 @@ declare_features! (
(removed, pushpop_unsafe, "1.2.0", None, None), (removed, pushpop_unsafe, "1.2.0", None, None),
(removed, quad_precision_float, "1.0.0", None, None), (removed, quad_precision_float, "1.0.0", None, None),
(removed, quote, "1.33.0", Some(29601), None), (removed, quote, "1.33.0", Some(29601), None),
(removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")),
(removed, reflect, "1.0.0", Some(27749), None), (removed, reflect, "1.0.0", Some(27749), None),
/// Allows using the `#[register_attr]` attribute. /// Allows using the `#[register_attr]` attribute.
(removed, register_attr, "1.65.0", Some(66080), (removed, register_attr, "1.65.0", Some(66080),

View file

@ -529,8 +529,6 @@ declare_features! (
(unstable, more_qualified_paths, "1.54.0", Some(86935)), (unstable, more_qualified_paths, "1.54.0", Some(86935)),
/// Allows the `#[must_not_suspend]` attribute. /// Allows the `#[must_not_suspend]` attribute.
(unstable, must_not_suspend, "1.57.0", Some(83310)), (unstable, must_not_suspend, "1.57.0", Some(83310)),
/// Make `mut` not reset the binding mode on edition >= 2024.
(incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)),
/// Allows `mut ref` and `mut ref mut` identifier patterns. /// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "1.79.0", Some(123076)), (incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on functions. /// Allows using `#[naked]` on functions.
@ -573,8 +571,6 @@ declare_features! (
(unstable, raw_ref_op, "1.41.0", Some(64490)), (unstable, raw_ref_op, "1.41.0", Some(64490)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
(incomplete, ref_pat_everywhere, "1.79.0", Some(123076)),
/// Allows using the `#[register_tool]` attribute. /// Allows using the `#[register_tool]` attribute.
(unstable, register_tool, "1.41.0", Some(66079)), (unstable, register_tool, "1.41.0", Some(66079)),
/// Allows the `#[repr(i128)]` attribute for enums. /// Allows the `#[repr(i128)]` attribute for enums.

View file

@ -1671,6 +1671,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut error_happened = false; let mut error_happened = false;
if variant.fields.len() != remaining_fields.len() {
// Some field is defined more than once. Make sure we don't try to
// instantiate this struct in static/const context.
let guar =
self.dcx().span_delayed_bug(expr.span, "struct fields have non-unique names");
self.set_tainted_by_errors(guar);
error_happened = true;
}
// Type-check each field. // Type-check each field.
for (idx, field) in hir_fields.iter().enumerate() { for (idx, field) in hir_fields.iter().enumerate() {
let ident = tcx.adjust_ident(field.ident, variant.def_id); let ident = tcx.adjust_ident(field.ident, variant.def_id);

View file

@ -12,7 +12,7 @@ use rustc_infer::infer;
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::{lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS, parse::feature_err};
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -335,9 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match adjust_mode { match adjust_mode {
AdjustMode::Pass => (expected, def_br, max_ref_mutbl), AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut), AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
AdjustMode::Peel => { AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl)
}
} }
} }
@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>, pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
mut def_br: ByRef, mut def_br: ByRef,
max_peelable_mutability: Mutability, mut max_ref_mutbl: MutblCap,
mut max_ref_mutability: MutblCap,
) -> (Ty<'tcx>, ByRef, MutblCap) { ) -> (Ty<'tcx>, ByRef, MutblCap) {
let mut expected = self.try_structurally_resolve_type(pat.span, expected); let mut expected = self.try_structurally_resolve_type(pat.span, expected);
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
@ -421,9 +418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// //
// See the examples in `ui/match-defbm*.rs`. // See the examples in `ui/match-defbm*.rs`.
let mut pat_adjustments = vec![]; let mut pat_adjustments = vec![];
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
&& inner_mutability <= max_peelable_mutability
{
debug!("inspecting {:?}", expected); debug!("inspecting {:?}", expected);
debug!("current discriminant is Ref, inserting implicit deref"); debug!("current discriminant is Ref, inserting implicit deref");
@ -443,10 +438,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
} }
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { if self.tcx.features().ref_pat_eat_one_layer_2024 {
def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl()); def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
if def_br == ByRef::Yes(Mutability::Not) { if def_br == ByRef::Yes(Mutability::Not) {
max_ref_mutability = MutblCap::Not; max_ref_mutbl = MutblCap::Not;
} }
} }
@ -458,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.insert(pat.hir_id, pat_adjustments); .insert(pat.hir_id, pat_adjustments);
} }
(expected, def_br, max_ref_mutability) (expected, def_br, max_ref_mutbl)
} }
fn check_pat_lit( fn check_pat_lit(
@ -674,17 +669,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Determine the binding mode... // Determine the binding mode...
let bm = match user_bind_annot { let bm = match user_bind_annot {
// `mut` resets binding mode on edition <= 2021 BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
BindingMode(ByRef::No, Mutability::Mut) if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
if !(pat.span.at_least_rust_2024() if !self.tcx.features().mut_ref {
&& self.tcx.features().mut_preserve_binding_mode_2024) feature_err(
&& matches!(def_br, ByRef::Yes(_)) => &self.tcx.sess,
{ sym::mut_ref,
self.typeck_results pat.span.until(ident.span),
.borrow_mut() "binding cannot be both mutable and by-reference",
.rust_2024_migration_desugared_pats_mut() )
.insert(pat_info.top_info.hir_id); .emit();
BindingMode(ByRef::No, Mutability::Mut) }
BindingMode(def_br, Mutability::Mut)
} else {
// `mut` resets binding mode on edition <= 2021
self.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.insert(pat_info.top_info.hir_id);
BindingMode(ByRef::No, Mutability::Mut)
}
} }
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
BindingMode(ByRef::Yes(_), _) => user_bind_annot, BindingMode(ByRef::Yes(_), _) => user_bind_annot,
@ -2126,57 +2131,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
mut expected: Ty<'tcx>, mut expected: Ty<'tcx>,
mut pat_info: PatInfo<'tcx, '_>, mut pat_info: PatInfo<'tcx, '_>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
// FIXME: repace with `bool` once final decision on 1 vs 2 layers is made let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
#[derive(Clone, Copy, Debug, PartialEq, Eq)] let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
enum MatchErgonomicsMode {
EatOneLayer,
EatTwoLayers,
Legacy,
}
let match_ergonomics_mode = let pat_prefix_span =
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
MatchErgonomicsMode::EatOneLayer
} else if self.tcx.features().ref_pat_everywhere {
MatchErgonomicsMode::EatTwoLayers
} else {
MatchErgonomicsMode::Legacy
};
let mut inherited_ref_mutbl_match = false; if no_ref_mut_behind_and {
if match_ergonomics_mode != MatchErgonomicsMode::Legacy {
if pat_mutbl == Mutability::Not { if pat_mutbl == Mutability::Not {
// Prevent the inner pattern from binding with `ref mut`. // Prevent the inner pattern from binding with `ref mut`.
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not( pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)),
);
} }
} else {
pat_info.max_ref_mutbl = MutblCap::Mut;
}
if new_match_ergonomics {
if let ByRef::Yes(inh_mut) = pat_info.binding_mode { if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
inherited_ref_mutbl_match = pat_mutbl <= inh_mut; // ref pattern consumes inherited reference
}
if inherited_ref_mutbl_match { if pat_mutbl > inh_mut {
pat_info.binding_mode = ByRef::No; // Tried to match inherited `ref` with `&mut`, which is an error
if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer { let err_msg = "cannot match inherited `&` with `&mut` pattern";
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); let err = if let Some(span) = pat_prefix_span {
self.check_pat(inner, expected, pat_info); let mut err = self.dcx().struct_span_err(span, err_msg);
return expected; err.span_suggestion_verbose(
span,
"replace this `&mut` pattern with `&`",
"&",
Applicability::MachineApplicable,
);
err
} else {
self.dcx().struct_span_err(pat.span, err_msg)
};
err.emit();
} }
} else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer
&& pat_mutbl == Mutability::Mut pat_info.binding_mode = ByRef::No;
{ self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
// `&mut` patterns pell off `&` references self.check_pat(inner, expected, pat_info);
let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references( return expected;
pat,
expected,
pat_info.binding_mode,
Mutability::Not,
pat_info.max_ref_mutbl,
);
expected = new_expected;
pat_info.binding_mode = new_bm;
pat_info.max_ref_mutbl = max_ref_mutbl;
} }
} else { } else {
// Reset binding mode on old editions // Reset binding mode on old editions
@ -2189,8 +2184,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.rust_2024_migration_desugared_pats_mut() .rust_2024_migration_desugared_pats_mut()
.insert(pat_info.top_info.hir_id); .insert(pat_info.top_info.hir_id);
} }
pat_info.max_ref_mutbl = MutblCap::Mut;
} }
let tcx = self.tcx; let tcx = self.tcx;
@ -2205,34 +2198,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the bad interactions of the given hack detailed in (note_1). // the bad interactions of the given hack detailed in (note_1).
debug!("check_pat_ref: expected={:?}", expected); debug!("check_pat_ref: expected={:?}", expected);
match *expected.kind() { match *expected.kind() {
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => { ty::Ref(_, r_ty, r_mutbl)
if r_mutbl == Mutability::Not if (new_match_ergonomics && r_mutbl >= pat_mutbl)
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy || r_mutbl == pat_mutbl =>
{ {
if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
pat_info.max_ref_mutbl = MutblCap::Not; pat_info.max_ref_mutbl = MutblCap::Not;
} }
(expected, r_ty) (expected, r_ty)
} }
// `&` pattern eats `&mut` reference
ty::Ref(_, r_ty, Mutability::Mut)
if pat_mutbl == Mutability::Not
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy =>
{
(expected, r_ty)
}
_ if inherited_ref_mutbl_match
&& match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers =>
{
// We already matched against a match-ergonmics inserted reference,
// so we don't need to match against a reference from the original type.
// Save this info for use in lowering later
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
(expected, expected)
}
_ => { _ => {
let inner_ty = self.next_ty_var(inner.span); let inner_ty = self.next_ty_var(inner.span);
let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty); let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);

View file

@ -88,6 +88,33 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
} }
} }
fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool {
match kind {
// Allow calls to deprecated-safe unsafe functions if the caller is
// from an edition before 2024.
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
{
self.tcx.emit_node_span_lint(
DEPRECATED_SAFE,
self.hir_context,
span,
CallToDeprecatedSafeFnRequiresUnsafe {
span,
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
},
},
);
true
}
_ => false,
}
}
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) { fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed(); let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
match self.safety_context { match self.safety_context {
@ -101,43 +128,29 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
} }
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {} SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
SafetyContext::UnsafeFn => { SafetyContext::UnsafeFn => {
// unsafe_op_in_unsafe_fn is disallowed let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
kind.emit_unsafe_op_in_unsafe_fn_lint( if !deprecated_safe_fn {
self.tcx, // unsafe_op_in_unsafe_fn is disallowed
self.hir_context, kind.emit_unsafe_op_in_unsafe_fn_lint(
span, self.tcx,
self.suggest_unsafe_block,
);
self.suggest_unsafe_block = false;
}
SafetyContext::Safe => match kind {
// Allow calls to deprecated-safe unsafe functions if the
// caller is from an edition before 2024.
UnsafeOpKind::CallToUnsafeFunction(Some(id))
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
{
self.tcx.emit_node_span_lint(
DEPRECATED_SAFE,
self.hir_context, self.hir_context,
span, span,
CallToDeprecatedSafeFnRequiresUnsafe { self.suggest_unsafe_block,
span, );
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), self.suggest_unsafe_block = false;
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
},
},
)
} }
_ => kind.emit_requires_unsafe_err( }
self.tcx, SafetyContext::Safe => {
span, let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
self.hir_context, if !deprecated_safe_fn {
unsafe_op_in_unsafe_fn_allowed, kind.emit_requires_unsafe_err(
), self.tcx,
}, span,
self.hir_context,
unsafe_op_in_unsafe_fn_allowed,
);
}
}
} }
} }

View file

@ -29,7 +29,7 @@ macro_rules! submodule_helper {
} }
macro_rules! book { macro_rules! book {
($($name:ident, $path:expr, $book_name:expr $(, submodule $(= $submodule:literal)? )? ;)+) => { ($($name:ident, $path:expr, $book_name:expr, $lang:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
$( $(
#[derive(Debug, Clone, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct $name { pub struct $name {
@ -61,6 +61,7 @@ macro_rules! book {
name: $book_name.to_owned(), name: $book_name.to_owned(),
src: builder.src.join($path), src: builder.src.join($path),
parent: Some(self), parent: Some(self),
languages: $lang.into(),
}) })
} }
} }
@ -74,15 +75,15 @@ macro_rules! book {
// FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules // FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
// and checking against it?). // and checking against it?).
book!( book!(
CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo"; CargoBook, "src/tools/cargo/src/doc", "cargo", &[], submodule = "src/tools/cargo";
ClippyBook, "src/tools/clippy/book", "clippy"; ClippyBook, "src/tools/clippy/book", "clippy", &[];
EditionGuide, "src/doc/edition-guide", "edition-guide", submodule; EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule; EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
Nomicon, "src/doc/nomicon", "nomicon", submodule; Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
Reference, "src/doc/reference", "reference", submodule; Reference, "src/doc/reference", "reference", &[], submodule;
RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule; RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja"], submodule;
RustdocBook, "src/doc/rustdoc", "rustdoc"; RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
StyleGuide, "src/doc/style-guide", "style-guide"; StyleGuide, "src/doc/style-guide", "style-guide", &[];
); );
#[derive(Debug, Clone, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@ -110,6 +111,7 @@ impl Step for UnstableBook {
name: "unstable-book".to_owned(), name: "unstable-book".to_owned(),
src: builder.md_doc_out(self.target).join("unstable-book"), src: builder.md_doc_out(self.target).join("unstable-book"),
parent: Some(self), parent: Some(self),
languages: vec![],
}) })
} }
} }
@ -120,6 +122,7 @@ struct RustbookSrc<P: Step> {
name: String, name: String,
src: PathBuf, src: PathBuf,
parent: Option<P>, parent: Option<P>,
languages: Vec<&'static str>,
} }
impl<P: Step> Step for RustbookSrc<P> { impl<P: Step> Step for RustbookSrc<P> {
@ -151,7 +154,19 @@ impl<P: Step> Step for RustbookSrc<P> {
builder.info(&format!("Rustbook ({target}) - {name}")); builder.info(&format!("Rustbook ({target}) - {name}"));
let _ = fs::remove_dir_all(&out); let _ = fs::remove_dir_all(&out);
builder.run(rustbook_cmd.arg("build").arg(src).arg("-d").arg(out)); builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out));
for lang in &self.languages {
let out = out.join(lang);
builder.info(&format!("Rustbook ({target}) - {name} - {lang}"));
let _ = fs::remove_dir_all(&out);
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
builder.run(
rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).arg("-l").arg(lang),
);
}
} }
if self.parent.is_some() { if self.parent.is_some() {
@ -214,6 +229,7 @@ impl Step for TheBook {
name: "book".to_owned(), name: "book".to_owned(),
src: absolute_path.clone(), src: absolute_path.clone(),
parent: Some(self), parent: Some(self),
languages: vec![],
}); });
// building older edition redirects // building older edition redirects
@ -225,6 +241,7 @@ impl Step for TheBook {
// There should only be one book that is marked as the parent for each target, so // There should only be one book that is marked as the parent for each target, so
// treat the other editions as not having a parent. // treat the other editions as not having a parent.
parent: Option::<Self>::None, parent: Option::<Self>::None,
languages: vec![],
}); });
} }
@ -1208,6 +1225,7 @@ impl Step for RustcBook {
name: "rustc".to_owned(), name: "rustc".to_owned(),
src: out_base, src: out_base,
parent: Some(self), parent: Some(self),
languages: vec![],
}); });
} }
} }

View file

@ -3,12 +3,12 @@
<!-- <!--
This page is currently (as of May 2024) the canonical place for describing the interaction This page is currently (as of May 2024) the canonical place for describing the interaction
between Cargo and --check-cfg. It is placed in the rustc book rather than the Cargo book between Cargo and --check-cfg. It is placed in the rustc book rather than the Cargo book
since check-cfg is primarely a Rust/rustc feature and is therefor consider by T-cargo to since check-cfg is primarily a Rust/rustc feature and is therefore considered by T-cargo to
be an implementation detail, at least --check-cfg and the unexpected_cfgs are owned by be an implementation detail, at least --check-cfg and the unexpected_cfgs are owned by
rustc, not Cargo. rustc, not Cargo.
--> -->
This document is intented to summarize the principal ways Cargo interacts with This document is intended to summarize the principal ways Cargo interacts with
the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide
individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
to the [Cargo book](../../cargo/index.html). to the [Cargo book](../../cargo/index.html).
@ -17,7 +17,7 @@ to the [Cargo book](../../cargo/index.html).
*See the [`[features]` section in the Cargo book][cargo-features] for more details.* *See the [`[features]` section in the Cargo book][cargo-features] for more details.*
With the `[features]` table Cargo provides a mechanism to express conditional compilation and With the `[features]` table, Cargo provides a mechanism to express conditional compilation and
optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as
expected. expected.
@ -32,16 +32,16 @@ my_feature = []
## `check-cfg` in `[lints.rust]` table ## `check-cfg` in `[lints.rust]` table
<!-- Note that T-Cargo considers `[lints.rust.unexpected_cfgs.check-cfg]` to be an <!-- Note that T-Cargo considers `lints.rust.unexpected_cfgs.check-cfg` to be an
implementation detail and is therefor not documented in Cargo, we therefor do that ourself --> implementation detail and is therefore documented here and not in Cargo. -->
*See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.* *See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.*
When using a staticlly known custom config (ie. not dependant on a build-script), Cargo provides When using a statically known custom config (i.e., not dependent on a build-script), Cargo provides
the custom lint config `check-cfg` under `[lints.rust.unexpected_cfgs]`. the custom lint config `check-cfg` under `[lints.rust.unexpected_cfgs]`.
It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when
the list of expected cfgs is known is advance. the list of expected cfgs is known in advance.
`Cargo.toml`: `Cargo.toml`:
```toml ```toml

View file

@ -9,6 +9,7 @@ clap = "4.0.32"
env_logger = "0.11" env_logger = "0.11"
mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" } mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" } mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
mdbook-i18n-helpers = "0.3.3"
[dependencies.mdbook] [dependencies.mdbook]
version = "0.4.37" version = "0.4.37"

View file

@ -7,6 +7,7 @@ use clap::{arg, ArgMatches, Command};
use mdbook::errors::Result as Result3; use mdbook::errors::Result as Result3;
use mdbook::MDBook; use mdbook::MDBook;
use mdbook_i18n_helpers::preprocessors::Gettext;
use mdbook_trpl_listing::TrplListing; use mdbook_trpl_listing::TrplListing;
use mdbook_trpl_note::TrplNote; use mdbook_trpl_note::TrplNote;
@ -19,6 +20,11 @@ fn main() {
.required(false) .required(false)
.value_parser(clap::value_parser!(PathBuf)); .value_parser(clap::value_parser!(PathBuf));
let l_arg = arg!(-l --"lang" <LANGUAGE>
"The output language")
.required(false)
.value_parser(clap::value_parser!(String));
let dir_arg = arg!([dir] "Root directory for the book\n\ let dir_arg = arg!([dir] "Root directory for the book\n\
(Defaults to the current directory when omitted)") (Defaults to the current directory when omitted)")
.value_parser(clap::value_parser!(PathBuf)); .value_parser(clap::value_parser!(PathBuf));
@ -33,6 +39,7 @@ fn main() {
Command::new("build") Command::new("build")
.about("Build the book from the markdown files") .about("Build the book from the markdown files")
.arg(d_arg) .arg(d_arg)
.arg(l_arg)
.arg(&dir_arg), .arg(&dir_arg),
) )
.subcommand( .subcommand(
@ -63,6 +70,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
let book_dir = get_book_dir(args); let book_dir = get_book_dir(args);
let mut book = load_book(&book_dir)?; let mut book = load_book(&book_dir)?;
if let Some(lang) = args.get_one::<String>("lang") {
let gettext = Gettext;
book.with_preprocessor(gettext);
book.config.set("book.language", lang).unwrap();
}
// Set this to allow us to catch bugs in advance. // Set this to allow us to catch bugs in advance.
book.config.build.create_missing = false; book.config.build.create_missing = false;

View file

@ -1,12 +0,0 @@
//@ known-bug: rust-lang/rust#124552
struct B;
struct Foo {
b: u32,
b: B,
}
static BAR: Foo = Foo { b: B };
fn main() {}

View file

@ -0,0 +1,13 @@
//@ run-pass
// Issue #122622: `#[derive(Clone)]` should work for HRTB function type taking an associated type
#![allow(dead_code)]
trait SomeTrait {
type SomeType<'a>;
}
#[derive(Clone)]
struct Foo<T: SomeTrait> {
x: for<'a> fn(T::SomeType<'a>)
}
fn main() {}

View file

@ -1,14 +0,0 @@
pub fn main() {
if let Some(Some(&x)) = &Some(&Some(0)) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
if let Some(&Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
}

View file

@ -1,49 +0,0 @@
error[E0308]: mismatched types
--> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(Some(x)) = &Some(&Some(0)) {
| ~
error[E0308]: mismatched types
--> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
|
LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
| |
| expected `Option<{integer}>`, found `&_`
|
= note: expected enum `Option<{integer}>`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
| |
| expected integer, found `&mut _`
|
= note: expected type `{integer}`
found mutable reference `&mut _`
note: to declare a mutable binding use: `mut x`
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
| ^^^^^^
help: consider removing `&mut` from the pattern
|
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
| ~
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -23,9 +23,6 @@ pub fn main() {
if let Some(Some(&x)) = &Some(&Some(0)) { if let Some(Some(&x)) = &Some(&Some(0)) {
let _: u32 = x; let _: u32 = x;
} }
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
let _: u32 = x;
}
if let Some(&Some(&x)) = &mut Some(&Some(0)) { if let Some(&Some(&x)) = &mut Some(&Some(0)) {
let _: u32 = x; let _: u32 = x;
} }
@ -35,9 +32,6 @@ pub fn main() {
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
let _: &u32 = x; let _: &u32 = x;
} }
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
let _: &u32 = x;
}
if let &Some(Some(x)) = &Some(&mut Some(0)) { if let &Some(Some(x)) = &Some(&mut Some(0)) {
let _: &u32 = x; let _: &u32 = x;
} }
@ -59,13 +53,4 @@ pub fn main() {
if let Some(&Some(x)) = &mut Some(Some(0)) { if let Some(&Some(x)) = &mut Some(Some(0)) {
let _: u32 = x; let _: u32 = x;
} }
let &mut x = &&mut 0;
let _: &u32 = x;
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
let _: &u32 = x;
let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
let _: &u32 = x;
} }

View file

@ -5,26 +5,26 @@
pub fn main() { pub fn main() {
if let Some(&mut Some(&_)) = &Some(&Some(0)) { if let Some(&mut Some(&_)) = &Some(&Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
if let Some(&Some(x)) = &mut Some(&Some(0)) { if let Some(&Some(x)) = &mut Some(&Some(0)) {
let _: &mut u32 = x; let _: &mut u32 = x;
//~^ ERROR: mismatched types //~^ ERROR: mismatched types
} }
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
if let Some(&mut Some(x)) = &Some(Some(0)) { if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
if let Some(&mut Some(x)) = &Some(Some(0)) { if let Some(&mut Some(x)) = &Some(Some(0)) {
//~^ ERROR: mismatched types //~^ ERROR: cannot match inherited `&` with `&mut` pattern
} }
let &mut _ = &&0; let &mut _ = &&0;
@ -32,4 +32,31 @@ pub fn main() {
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
//~^ ERROR: mismatched types //~^ ERROR: mismatched types
if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
}
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
}
let &mut _ = &&mut 0;
//~^ ERROR: mismatched types
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
//~^ ERROR: mismatched types
let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
//~^ ERROR: mismatched types
struct Foo(u8);
let Foo(mut a) = &Foo(0);
//~^ ERROR: binding cannot be both mutable and by-reference
a = &42;
let Foo(mut a) = &mut Foo(0);
//~^ ERROR: binding cannot be both mutable and by-reference
a = &mut 42;
} }

View file

@ -1,24 +1,24 @@
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
| |
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` | ^^^^^
| |
| expected `Option<{integer}>`, found `&mut _`
| |
= note: expected enum `Option<{integer}>` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(&_)) = &Some(&Some(0)) {
| ~
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23
| |
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
| ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` | ^^^^^
| |
| expected integer, found `&mut _`
| |
= note: expected type `{integer}` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
| ~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
@ -31,49 +31,49 @@ LL | let _: &mut u32 = x;
= note: expected mutable reference `&mut u32` = note: expected mutable reference `&mut u32`
found reference `&{integer}` found reference `&{integer}`
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
| |
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` | ^^^^^
| |
| expected integer, found `&mut _`
| |
= note: expected type `{integer}` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) {
| ~
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
| |
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>` | ^^^^^
| |
| expected integer, found `&mut _`
| |
= note: expected type `{integer}` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
| ~
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
| |
LL | if let Some(&mut Some(x)) = &Some(Some(0)) { LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>` | ^^^^^
| |
| expected `Option<{integer}>`, found `&mut _`
| |
= note: expected enum `Option<{integer}>` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ~
error[E0308]: mismatched types error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
| |
LL | if let Some(&mut Some(x)) = &Some(Some(0)) { LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>` | ^^^^^
| |
| expected `Option<{integer}>`, found `&mut _`
| |
= note: expected enum `Option<{integer}>` help: replace this `&mut` pattern with `&`
found mutable reference `&mut _` |
LL | if let Some(&Some(x)) = &Some(Some(0)) {
| ~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9 --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
@ -81,9 +81,9 @@ error[E0308]: mismatched types
LL | let &mut _ = &&0; LL | let &mut _ = &&0;
| ^^^^^^ --- this expression has type `&&{integer}` | ^^^^^^ --- this expression has type `&&{integer}`
| | | |
| expected integer, found `&mut _` | types differ in mutability
| |
= note: expected type `{integer}` = note: expected reference `&&{integer}`
found mutable reference `&mut _` found mutable reference `&mut _`
error[E0308]: mismatched types error[E0308]: mismatched types
@ -92,11 +92,87 @@ error[E0308]: mismatched types
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
| | | |
| expected integer, found `&mut _` | types differ in mutability
| |
= note: expected type `{integer}` = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
found mutable reference `&mut _` found mutable reference `&mut _`
error: aborting due to 9 previous errors error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17
|
LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
| ^^^^^
|
help: replace this `&mut` pattern with `&`
|
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
| ~
For more information about this error, try `rustc --explain E0308`. error: cannot match inherited `&` with `&mut` pattern
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22
|
LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
| ^^^^^
|
help: replace this `&mut` pattern with `&`
|
LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) {
| ~
error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9
|
LL | let &mut _ = &&mut 0;
| ^^^^^^ ------- this expression has type `&&mut {integer}`
| |
| types differ in mutability
|
= note: expected reference `&&mut {integer}`
found mutable reference `&mut _`
error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9
|
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
| ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
| |
| types differ in mutability
|
= note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
found mutable reference `&mut _`
error[E0308]: mismatched types
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14
|
LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
| ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
| |
| types differ in mutability
|
= note: expected reference `&&&&mut &&&mut &mut {integer}`
found mutable reference `&mut _`
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^
|
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: binding cannot be both mutable and by-reference
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^
|
= note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
= help: add `#![feature(mut_ref)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 16 previous errors
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.

View file

@ -1,12 +0,0 @@
#![allow(incomplete_features)]
#![feature(ref_pat_everywhere)]
pub fn main() {
if let Some(&x) = Some(0) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
if let Some(&mut x) = Some(&0) {
//~^ ERROR: mismatched types [E0308]
let _: u32 = x;
}
}

View file

@ -1,38 +0,0 @@
error[E0308]: mismatched types
--> $DIR/ref_pat_everywhere-fail.rs:4:17
|
LL | if let Some(&x) = Some(0) {
| ^^ ------- this expression has type `Option<{integer}>`
| |
| expected integer, found `&_`
|
= note: expected type `{integer}`
found reference `&_`
help: consider removing `&` from the pattern
|
LL | if let Some(x) = Some(0) {
| ~
error[E0308]: mismatched types
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
LL | if let Some(&mut x) = Some(&0) {
| ^^^^^^ -------- this expression has type `Option<&{integer}>`
| |
| types differ in mutability
|
= note: expected reference `&{integer}`
found mutable reference `&mut _`
note: to declare a mutable binding use: `mut x`
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
LL | if let Some(&mut x) = Some(&0) {
| ^^^^^^
help: consider removing `&mut` from the pattern
|
LL | if let Some(x) = Some(&0) {
| ~
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,24 +0,0 @@
//@ run-pass
#![allow(incomplete_features)]
#![feature(ref_pat_everywhere)]
pub fn main() {
if let Some(Some(&x)) = &Some(&Some(0)) {
let _: u32 = x;
}
if let Some(&Some(x)) = &Some(Some(0)) {
let _: u32 = x;
}
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
let _: u32 = x;
}
if let Some(Some(&x)) = &Some(&mut Some(0)) {
let _: u32 = x;
}
if let &Some(x) = &mut Some(0) {
let _: u32 = x;
}
if let Some(&x) = &mut Some(0) {
let _: u32 = x;
}
}

View file

@ -1,14 +0,0 @@
//@ edition: 2024
//@ compile-flags: -Zunstable-options
struct Foo(u8);
fn main() {
let Foo(mut a) = &Foo(0);
a = &42;
//~^ ERROR: mismatched types
let Foo(mut a) = &mut Foo(0);
a = &mut 42;
//~^ ERROR: mismatched types
}

View file

@ -1,31 +0,0 @@
error[E0308]: mismatched types
--> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:8:9
|
LL | let Foo(mut a) = &Foo(0);
| ----- expected due to the type of this binding
LL | a = &42;
| ^^^ expected `u8`, found `&{integer}`
|
help: consider removing the borrow
|
LL - a = &42;
LL + a = 42;
|
error[E0308]: mismatched types
--> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:12:9
|
LL | let Foo(mut a) = &mut Foo(0);
| ----- expected due to the type of this binding
LL | a = &mut 42;
| ^^^^^^^ expected `u8`, found `&mut {integer}`
|
help: consider removing the borrow
|
LL - a = &mut 42;
LL + a = 42;
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -2,7 +2,7 @@
//@ run-rustfix //@ run-rustfix
//@ rustfix-only-machine-applicable //@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs //@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
#![deny(rust_2024_incompatible_pat)] #![deny(rust_2024_incompatible_pat)]

View file

@ -2,7 +2,7 @@
//@ run-rustfix //@ run-rustfix
//@ rustfix-only-machine-applicable //@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs //@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
#![deny(rust_2024_incompatible_pat)] #![deny(rust_2024_incompatible_pat)]

View file

@ -1,6 +1,6 @@
//@ edition: 2021 //@ edition: 2021
//@ compile-flags: -Zunstable-options //@ compile-flags: -Zunstable-options
#![feature(mut_preserve_binding_mode_2024)] #![feature(ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
struct Foo(u8); struct Foo(u8);

View file

@ -1,7 +1,7 @@
//@ run-pass //@ run-pass
//@ edition: 2024 //@ edition: 2024
//@ compile-flags: -Zunstable-options //@ compile-flags: -Zunstable-options
#![feature(mut_preserve_binding_mode_2024)] #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)] #![allow(incomplete_features, unused)]
struct Foo(u8); struct Foo(u8);

View file

@ -0,0 +1,9 @@
//@ edition: 2021
//@ run-pass
#![allow(incomplete_features)]
#![feature(ref_pat_eat_one_layer_2024)]
fn main() {
let &[[x]] = &[&mut [42]];
let _: &i32 = x;
}

View file

@ -1,5 +1,24 @@
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:9
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/unsafe-env.rs:9:1
|
LL | unsafe fn unsafe_fn() {
| ^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/unsafe-env.rs:8:8
|
LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block
--> $DIR/unsafe-env.rs:23:5 --> $DIR/unsafe-env.rs:33:5
| |
LL | unsafe_fn(); LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^ call to unsafe function
@ -7,17 +26,17 @@ LL | unsafe_fn();
= note: consult the function's documentation for information on how to avoid undefined behavior = note: consult the function's documentation for information on how to avoid undefined behavior
error: unnecessary `unsafe` block error: unnecessary `unsafe` block
--> $DIR/unsafe-env.rs:26:5 --> $DIR/unsafe-env.rs:36:5
| |
LL | unsafe { LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block | ^^^^^^ unnecessary `unsafe` block
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/unsafe-env.rs:11:8 --> $DIR/unsafe-env.rs:21:8
| |
LL | #[deny(unused_unsafe)] LL | #[deny(unused_unsafe)]
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0133`. For more information about this error, try `rustc --explain E0133`.

View file

@ -1,5 +1,42 @@
error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:10:5
|
LL | env::set_var("FOO", "BAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/unsafe-env.rs:9:1
|
LL | unsafe fn unsafe_fn() {
| ^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/unsafe-env.rs:8:8
|
LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:12:5
|
LL | env::remove_var("FOO");
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:9
|
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:13:5 --> $DIR/unsafe-env.rs:23:5
| |
LL | env::set_var("FOO", "BAR"); LL | env::set_var("FOO", "BAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@ -7,7 +44,7 @@ LL | env::set_var("FOO", "BAR");
= note: consult the function's documentation for information on how to avoid undefined behavior = note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:15:5 --> $DIR/unsafe-env.rs:25:5
| |
LL | env::remove_var("FOO"); LL | env::remove_var("FOO");
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@ -15,7 +52,7 @@ LL | env::remove_var("FOO");
= note: consult the function's documentation for information on how to avoid undefined behavior = note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
--> $DIR/unsafe-env.rs:23:5 --> $DIR/unsafe-env.rs:33:5
| |
LL | unsafe_fn(); LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^ call to unsafe function
@ -23,17 +60,17 @@ LL | unsafe_fn();
= note: consult the function's documentation for information on how to avoid undefined behavior = note: consult the function's documentation for information on how to avoid undefined behavior
error: unnecessary `unsafe` block error: unnecessary `unsafe` block
--> $DIR/unsafe-env.rs:26:5 --> $DIR/unsafe-env.rs:36:5
| |
LL | unsafe { LL | unsafe {
| ^^^^^^ unnecessary `unsafe` block | ^^^^^^ unnecessary `unsafe` block
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/unsafe-env.rs:11:8 --> $DIR/unsafe-env.rs:21:8
| |
LL | #[deny(unused_unsafe)] LL | #[deny(unused_unsafe)]
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: aborting due to 4 previous errors error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0133`. For more information about this error, try `rustc --explain E0133`.

View file

@ -5,7 +5,17 @@
use std::env; use std::env;
unsafe fn unsafe_fn() {} #[deny(unsafe_op_in_unsafe_fn)]
unsafe fn unsafe_fn() {
env::set_var("FOO", "BAR");
//[e2024]~^ ERROR call to unsafe function `std::env::set_var` is unsafe
env::remove_var("FOO");
//[e2024]~^ ERROR call to unsafe function `std::env::remove_var` is unsafe
if false {
unsafe_fn();
//~^ ERROR call to unsafe function `unsafe_fn` is unsafe
}
}
fn safe_fn() {} fn safe_fn() {}
#[deny(unused_unsafe)] #[deny(unused_unsafe)]

View file

@ -1,12 +1,16 @@
//@ known-bug: rust-lang/rust #124464 // Don't const eval fields with ambiguous layout.
// See issues #125842 and #124464.
enum TestOption<T> { enum TestOption<T> {
TestSome(T), TestSome(T),
TestSome(T), TestSome(T),
//~^ ERROR the name `TestSome` is defined multiple times
} }
pub struct Request { pub struct Request {
bar: TestOption<u64>, bar: TestOption<u64>,
bar: u8, bar: u8,
//~^ ERROR field `bar` is already declared
} }
fn default_instance() -> &'static Request { fn default_instance() -> &'static Request {

View file

@ -0,0 +1,22 @@
error[E0428]: the name `TestSome` is defined multiple times
--> $DIR/duplicated-fields-issue-124464.rs:6:5
|
LL | TestSome(T),
| ----------- previous definition of the type `TestSome` here
LL | TestSome(T),
| ^^^^^^^^^^^ `TestSome` redefined here
|
= note: `TestSome` must be defined only once in the type namespace of this enum
error[E0124]: field `bar` is already declared
--> $DIR/duplicated-fields-issue-124464.rs:12:5
|
LL | bar: TestOption<u64>,
| -------------------- `bar` first declared here
LL | bar: u8,
| ^^^^^^^ field already declared
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0124, E0428.
For more information about an error, try `rustc --explain E0124`.

View file

@ -0,0 +1,21 @@
// Do not try to evaluate static initalizers that reference
// ill-defined types. This used to be an ICE.
// See issues #125842 and #124464.
struct Struct {
field: Option<u8>,
field: u8,
//~^ ERROR field `field` is already declared
}
static STATIC_A: Struct = Struct {
field: 1
};
static STATIC_B: Struct = {
let field = 1;
Struct {
field,
}
};
fn main() {}

View file

@ -0,0 +1,11 @@
error[E0124]: field `field` is already declared
--> $DIR/duplicated-fields-issue-125842.rs:6:5
|
LL | field: Option<u8>,
| ----------------- `field` first declared here
LL | field: u8,
| ^^^^^^^^^ field already declared
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0124`.