mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
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:
commit
2b6a34273d
148
Cargo.lock
148
Cargo.lock
@ -372,7 +372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata 0.3.9",
|
||||
"regex-automata 0.3.7",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -2206,6 +2206,21 @@ dependencies = [
|
||||
"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]]
|
||||
name = "linkchecker"
|
||||
version = "0.1.0"
|
||||
@ -2214,6 +2229,12 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "lint-docs"
|
||||
version = "0.1.0"
|
||||
@ -2364,6 +2385,25 @@ dependencies = [
|
||||
"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]]
|
||||
name = "mdbook-trpl-listing"
|
||||
version = "0.1.0"
|
||||
@ -2650,6 +2690,28 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "opener"
|
||||
version = "0.6.1"
|
||||
@ -2968,6 +3030,29 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "polonius-engine"
|
||||
version = "0.13.0"
|
||||
@ -3126,6 +3211,15 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "quine-mc_cluskey"
|
||||
version = "0.2.4"
|
||||
@ -3261,12 +3355,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.8.4"
|
||||
version = "1.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
|
||||
checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.3.7",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
@ -3290,9 +3385,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.9"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
|
||||
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-lite"
|
||||
@ -3367,6 +3467,7 @@ dependencies = [
|
||||
"clap",
|
||||
"env_logger",
|
||||
"mdbook",
|
||||
"mdbook-i18n-helpers",
|
||||
"mdbook-trpl-listing",
|
||||
"mdbook-trpl-note",
|
||||
]
|
||||
@ -5372,6 +5473,28 @@ dependencies = [
|
||||
"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]]
|
||||
name = "sysinfo"
|
||||
version = "0.30.12"
|
||||
@ -5497,6 +5620,12 @@ dependencies = [
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||
|
||||
[[package]]
|
||||
name = "thin-vec"
|
||||
version = "0.2.13"
|
||||
@ -6476,6 +6605,15 @@ dependencies = [
|
||||
"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]]
|
||||
name = "yansi-term"
|
||||
version = "0.1.2"
|
||||
|
@ -412,6 +412,15 @@ fn find_type_parameters(
|
||||
|
||||
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
||||
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
|
||||
&& let Some(segment) = path.segments.first()
|
||||
&& 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.
|
||||
|
@ -128,6 +128,8 @@ declare_features! (
|
||||
/// Allows the use of type alias impl trait in function return positions
|
||||
(removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
|
||||
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),
|
||||
Some("subsumed by `#![feature(allocator_internals)]`")),
|
||||
/// 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, quad_precision_float, "1.0.0", None, 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),
|
||||
/// Allows using the `#[register_attr]` attribute.
|
||||
(removed, register_attr, "1.65.0", Some(66080),
|
||||
|
@ -529,8 +529,6 @@ declare_features! (
|
||||
(unstable, more_qualified_paths, "1.54.0", Some(86935)),
|
||||
/// Allows the `#[must_not_suspend]` attribute.
|
||||
(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.
|
||||
(incomplete, mut_ref, "1.79.0", Some(123076)),
|
||||
/// Allows using `#[naked]` on functions.
|
||||
@ -573,8 +571,6 @@ declare_features! (
|
||||
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
||||
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
|
||||
(incomplete, ref_pat_eat_one_layer_2024, "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.
|
||||
(unstable, register_tool, "1.41.0", Some(66079)),
|
||||
/// Allows the `#[repr(i128)]` attribute for enums.
|
||||
|
@ -1671,6 +1671,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
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.
|
||||
for (idx, field) in hir_fields.iter().enumerate() {
|
||||
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||
|
@ -12,7 +12,7 @@ use rustc_infer::infer;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
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::hygiene::DesugaringKind;
|
||||
use rustc_span::source_map::Spanned;
|
||||
@ -335,9 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match adjust_mode {
|
||||
AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
|
||||
AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
|
||||
AdjustMode::Peel => {
|
||||
self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl)
|
||||
}
|
||||
AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
mut def_br: ByRef,
|
||||
max_peelable_mutability: Mutability,
|
||||
mut max_ref_mutability: MutblCap,
|
||||
mut max_ref_mutbl: MutblCap,
|
||||
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
||||
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,
|
||||
@ -421,9 +418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
//
|
||||
// See the examples in `ui/match-defbm*.rs`.
|
||||
let mut pat_adjustments = vec![];
|
||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
|
||||
&& inner_mutability <= max_peelable_mutability
|
||||
{
|
||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
|
||||
debug!("inspecting {:?}", expected);
|
||||
|
||||
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 {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl());
|
||||
if self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
|
||||
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);
|
||||
}
|
||||
|
||||
(expected, def_br, max_ref_mutability)
|
||||
(expected, def_br, max_ref_mutbl)
|
||||
}
|
||||
|
||||
fn check_pat_lit(
|
||||
@ -674,17 +669,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Determine the binding mode...
|
||||
let bm = match user_bind_annot {
|
||||
// `mut` resets binding mode on edition <= 2021
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
if !(pat.span.at_least_rust_2024()
|
||||
&& self.tcx.features().mut_preserve_binding_mode_2024)
|
||||
&& matches!(def_br, ByRef::Yes(_)) =>
|
||||
{
|
||||
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, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
if !self.tcx.features().mut_ref {
|
||||
feature_err(
|
||||
&self.tcx.sess,
|
||||
sym::mut_ref,
|
||||
pat.span.until(ident.span),
|
||||
"binding cannot be both mutable and by-reference",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
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::Yes(_), _) => user_bind_annot,
|
||||
@ -2126,57 +2131,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
mut expected: Ty<'tcx>,
|
||||
mut pat_info: PatInfo<'tcx, '_>,
|
||||
) -> Ty<'tcx> {
|
||||
// FIXME: repace with `bool` once final decision on 1 vs 2 layers is made
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum MatchErgonomicsMode {
|
||||
EatOneLayer,
|
||||
EatTwoLayers,
|
||||
Legacy,
|
||||
}
|
||||
let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
|
||||
let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
|
||||
|
||||
let match_ergonomics_mode =
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
MatchErgonomicsMode::EatOneLayer
|
||||
} else if self.tcx.features().ref_pat_everywhere {
|
||||
MatchErgonomicsMode::EatTwoLayers
|
||||
} else {
|
||||
MatchErgonomicsMode::Legacy
|
||||
};
|
||||
let pat_prefix_span =
|
||||
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
|
||||
|
||||
let mut inherited_ref_mutbl_match = false;
|
||||
if match_ergonomics_mode != MatchErgonomicsMode::Legacy {
|
||||
if no_ref_mut_behind_and {
|
||||
if pat_mutbl == Mutability::Not {
|
||||
// Prevent the inner pattern from binding with `ref mut`.
|
||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(
|
||||
inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)),
|
||||
);
|
||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
|
||||
}
|
||||
} else {
|
||||
pat_info.max_ref_mutbl = MutblCap::Mut;
|
||||
}
|
||||
|
||||
if new_match_ergonomics {
|
||||
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 {
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer {
|
||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||
self.check_pat(inner, expected, pat_info);
|
||||
return expected;
|
||||
if pat_mutbl > inh_mut {
|
||||
// Tried to match inherited `ref` with `&mut`, which is an error
|
||||
let err_msg = "cannot match inherited `&` with `&mut` pattern";
|
||||
let err = if let Some(span) = pat_prefix_span {
|
||||
let mut err = self.dcx().struct_span_err(span, err_msg);
|
||||
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
|
||||
{
|
||||
// `&mut` patterns pell off `&` references
|
||||
let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references(
|
||||
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;
|
||||
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||
self.check_pat(inner, expected, pat_info);
|
||||
return expected;
|
||||
}
|
||||
} else {
|
||||
// Reset binding mode on old editions
|
||||
@ -2189,8 +2184,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
}
|
||||
|
||||
pat_info.max_ref_mutbl = MutblCap::Mut;
|
||||
}
|
||||
|
||||
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).
|
||||
debug!("check_pat_ref: expected={:?}", expected);
|
||||
match *expected.kind() {
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => {
|
||||
if r_mutbl == Mutability::Not
|
||||
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy
|
||||
{
|
||||
ty::Ref(_, r_ty, r_mutbl)
|
||||
if (new_match_ergonomics && r_mutbl >= pat_mutbl)
|
||||
|| r_mutbl == pat_mutbl =>
|
||||
{
|
||||
if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
|
||||
pat_info.max_ref_mutbl = MutblCap::Not;
|
||||
}
|
||||
|
||||
(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 ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);
|
||||
|
@ -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) {
|
||||
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
|
||||
match self.safety_context {
|
||||
@ -101,43 +128,29 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
}
|
||||
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
|
||||
SafetyContext::UnsafeFn => {
|
||||
// unsafe_op_in_unsafe_fn is disallowed
|
||||
kind.emit_unsafe_op_in_unsafe_fn_lint(
|
||||
self.tcx,
|
||||
self.hir_context,
|
||||
span,
|
||||
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,
|
||||
let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
|
||||
if !deprecated_safe_fn {
|
||||
// unsafe_op_in_unsafe_fn is disallowed
|
||||
kind.emit_unsafe_op_in_unsafe_fn_lint(
|
||||
self.tcx,
|
||||
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(),
|
||||
},
|
||||
},
|
||||
)
|
||||
self.suggest_unsafe_block,
|
||||
);
|
||||
self.suggest_unsafe_block = false;
|
||||
}
|
||||
_ => kind.emit_requires_unsafe_err(
|
||||
self.tcx,
|
||||
span,
|
||||
self.hir_context,
|
||||
unsafe_op_in_unsafe_fn_allowed,
|
||||
),
|
||||
},
|
||||
}
|
||||
SafetyContext::Safe => {
|
||||
let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
|
||||
if !deprecated_safe_fn {
|
||||
kind.emit_requires_unsafe_err(
|
||||
self.tcx,
|
||||
span,
|
||||
self.hir_context,
|
||||
unsafe_op_in_unsafe_fn_allowed,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ macro_rules! submodule_helper {
|
||||
}
|
||||
|
||||
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)]
|
||||
pub struct $name {
|
||||
@ -61,6 +61,7 @@ macro_rules! book {
|
||||
name: $book_name.to_owned(),
|
||||
src: builder.src.join($path),
|
||||
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
|
||||
// and checking against it?).
|
||||
book!(
|
||||
CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo";
|
||||
ClippyBook, "src/tools/clippy/book", "clippy";
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
|
||||
Nomicon, "src/doc/nomicon", "nomicon", submodule;
|
||||
Reference, "src/doc/reference", "reference", submodule;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule;
|
||||
RustdocBook, "src/doc/rustdoc", "rustdoc";
|
||||
StyleGuide, "src/doc/style-guide", "style-guide";
|
||||
CargoBook, "src/tools/cargo/src/doc", "cargo", &[], submodule = "src/tools/cargo";
|
||||
ClippyBook, "src/tools/clippy/book", "clippy", &[];
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
|
||||
Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
|
||||
Reference, "src/doc/reference", "reference", &[], submodule;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja"], submodule;
|
||||
RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
|
||||
StyleGuide, "src/doc/style-guide", "style-guide", &[];
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
@ -110,6 +111,7 @@ impl Step for UnstableBook {
|
||||
name: "unstable-book".to_owned(),
|
||||
src: builder.md_doc_out(self.target).join("unstable-book"),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -120,6 +122,7 @@ struct RustbookSrc<P: Step> {
|
||||
name: String,
|
||||
src: PathBuf,
|
||||
parent: Option<P>,
|
||||
languages: Vec<&'static str>,
|
||||
}
|
||||
|
||||
impl<P: Step> Step for RustbookSrc<P> {
|
||||
@ -151,7 +154,19 @@ impl<P: Step> Step for RustbookSrc<P> {
|
||||
builder.info(&format!("Rustbook ({target}) - {name}"));
|
||||
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() {
|
||||
@ -214,6 +229,7 @@ impl Step for TheBook {
|
||||
name: "book".to_owned(),
|
||||
src: absolute_path.clone(),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
});
|
||||
|
||||
// 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
|
||||
// treat the other editions as not having a parent.
|
||||
parent: Option::<Self>::None,
|
||||
languages: vec![],
|
||||
});
|
||||
}
|
||||
|
||||
@ -1208,6 +1225,7 @@ impl Step for RustcBook {
|
||||
name: "rustc".to_owned(),
|
||||
src: out_base,
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
<!--
|
||||
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
|
||||
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
|
||||
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
|
||||
individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
|
||||
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.*
|
||||
|
||||
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
|
||||
expected.
|
||||
|
||||
@ -32,16 +32,16 @@ my_feature = []
|
||||
|
||||
## `check-cfg` in `[lints.rust]` table
|
||||
|
||||
<!-- 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 -->
|
||||
<!-- Note that T-Cargo considers `lints.rust.unexpected_cfgs.check-cfg` to be an
|
||||
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.*
|
||||
|
||||
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]`.
|
||||
|
||||
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`:
|
||||
```toml
|
||||
|
@ -9,6 +9,7 @@ clap = "4.0.32"
|
||||
env_logger = "0.11"
|
||||
mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
|
||||
mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
|
||||
mdbook-i18n-helpers = "0.3.3"
|
||||
|
||||
[dependencies.mdbook]
|
||||
version = "0.4.37"
|
||||
|
@ -7,6 +7,7 @@ use clap::{arg, ArgMatches, Command};
|
||||
|
||||
use mdbook::errors::Result as Result3;
|
||||
use mdbook::MDBook;
|
||||
use mdbook_i18n_helpers::preprocessors::Gettext;
|
||||
|
||||
use mdbook_trpl_listing::TrplListing;
|
||||
use mdbook_trpl_note::TrplNote;
|
||||
@ -19,6 +20,11 @@ fn main() {
|
||||
.required(false)
|
||||
.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\
|
||||
(Defaults to the current directory when omitted)")
|
||||
.value_parser(clap::value_parser!(PathBuf));
|
||||
@ -33,6 +39,7 @@ fn main() {
|
||||
Command::new("build")
|
||||
.about("Build the book from the markdown files")
|
||||
.arg(d_arg)
|
||||
.arg(l_arg)
|
||||
.arg(&dir_arg),
|
||||
)
|
||||
.subcommand(
|
||||
@ -63,6 +70,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
|
||||
let book_dir = get_book_dir(args);
|
||||
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.
|
||||
book.config.build.create_missing = false;
|
||||
|
||||
|
@ -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() {}
|
@ -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() {}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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`.
|
@ -23,9 +23,6 @@ pub fn main() {
|
||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
if let Some(&Some(&x)) = &mut Some(&Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
@ -35,9 +32,6 @@ pub fn main() {
|
||||
if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
if let &Some(Some(x)) = &Some(&mut Some(0)) {
|
||||
let _: &u32 = x;
|
||||
}
|
||||
@ -59,13 +53,4 @@ pub fn main() {
|
||||
if let Some(&Some(x)) = &mut Some(Some(0)) {
|
||||
let _: u32 = x;
|
||||
}
|
||||
|
||||
let &mut x = &&mut 0;
|
||||
let _: &u32 = x;
|
||||
|
||||
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||
let _: &u32 = x;
|
||||
|
||||
let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
|
||||
let _: &u32 = x;
|
||||
}
|
||||
|
@ -5,26 +5,26 @@
|
||||
|
||||
pub fn main() {
|
||||
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)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&Some(x)) = &mut Some(&Some(0)) {
|
||||
let _: &mut u32 = x;
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
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)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: cannot match inherited `&` with `&mut` pattern
|
||||
}
|
||||
|
||||
let &mut _ = &&0;
|
||||
@ -32,4 +32,31 @@ pub fn main() {
|
||||
|
||||
let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
//~^ 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
||||
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
|
||||
| ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
|
||||
@ -31,49 +31,49 @@ LL | let _: &mut u32 = x;
|
||||
= note: expected mutable reference `&mut u32`
|
||||
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
|
||||
|
|
||||
LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
|
||||
| ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
|
||||
| ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | if let Some(&mut Some(x)) = &Some(Some(0)) {
|
||||
| ^^^^^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||
| |
|
||||
| expected `Option<{integer}>`, found `&mut _`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: expected enum `Option<{integer}>`
|
||||
found mutable reference `&mut _`
|
||||
help: replace this `&mut` pattern with `&`
|
||||
|
|
||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||
| ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
|
||||
@ -81,9 +81,9 @@ error[E0308]: mismatched types
|
||||
LL | let &mut _ = &&0;
|
||||
| ^^^^^^ --- 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 _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -92,11 +92,87 @@ error[E0308]: mismatched types
|
||||
LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||
| ^^^^^^ ----------------------------- 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 _`
|
||||
|
||||
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`.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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`.
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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`.
|
@ -2,7 +2,7 @@
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ 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)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ 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)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ edition: 2021
|
||||
//@ compile-flags: -Zunstable-options
|
||||
#![feature(mut_preserve_binding_mode_2024)]
|
||||
#![feature(ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo(u8);
|
||||
|
@ -1,7 +1,7 @@
|
||||
//@ run-pass
|
||||
//@ edition: 2024
|
||||
//@ compile-flags: -Zunstable-options
|
||||
#![feature(mut_preserve_binding_mode_2024)]
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
|
||||
struct Foo(u8);
|
||||
|
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal file
9
tests/ui/pattern/no_ref_mut_behind_and.rs
Normal 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;
|
||||
}
|
@ -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
|
||||
--> $DIR/unsafe-env.rs:23:5
|
||||
--> $DIR/unsafe-env.rs:33:5
|
||||
|
|
||||
LL | unsafe_fn();
|
||||
| ^^^^^^^^^^^ 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
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/unsafe-env.rs:26:5
|
||||
--> $DIR/unsafe-env.rs:36:5
|
||||
|
|
||||
LL | unsafe {
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unsafe-env.rs:11:8
|
||||
--> $DIR/unsafe-env.rs:21:8
|
||||
|
|
||||
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`.
|
||||
|
@ -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
|
||||
--> $DIR/unsafe-env.rs:13:5
|
||||
--> $DIR/unsafe-env.rs:23:5
|
||||
|
|
||||
LL | env::set_var("FOO", "BAR");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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();
|
||||
| ^^^^^^^^^^^ 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
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/unsafe-env.rs:26:5
|
||||
--> $DIR/unsafe-env.rs:36:5
|
||||
|
|
||||
LL | unsafe {
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unsafe-env.rs:11:8
|
||||
--> $DIR/unsafe-env.rs:21:8
|
||||
|
|
||||
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`.
|
||||
|
@ -5,7 +5,17 @@
|
||||
|
||||
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() {}
|
||||
|
||||
#[deny(unused_unsafe)]
|
||||
|
@ -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> {
|
||||
TestSome(T),
|
||||
TestSome(T),
|
||||
//~^ ERROR the name `TestSome` is defined multiple times
|
||||
}
|
||||
|
||||
pub struct Request {
|
||||
bar: TestOption<u64>,
|
||||
bar: u8,
|
||||
//~^ ERROR field `bar` is already declared
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static Request {
|
22
tests/ui/static/duplicated-fields-issue-124464.stderr
Normal file
22
tests/ui/static/duplicated-fields-issue-124464.stderr
Normal 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`.
|
21
tests/ui/static/duplicated-fields-issue-125842.rs
Normal file
21
tests/ui/static/duplicated-fields-issue-125842.rs
Normal 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() {}
|
11
tests/ui/static/duplicated-fields-issue-125842.stderr
Normal file
11
tests/ui/static/duplicated-fields-issue-125842.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user